diff --git a/adapter/properties.cpp b/adapter/properties.cpp index 380af9347a0eb7a681f1c012c7e1b6e086b3346d..39dab72433343c9f3a34952eaf0a632d8ea4aae3 100644 --- a/adapter/properties.cpp +++ b/adapter/properties.cpp @@ -16,7 +16,6 @@ #include "properties.h" #include "hilog/log.h" #include - #include #include #include @@ -29,7 +28,6 @@ #include #include #include - #include #include #include @@ -46,18 +44,6 @@ static pthread_mutex_t g_persistDebugLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_privateLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_processFlowLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_domainFlowLock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t g_processQuotaLock = PTHREAD_MUTEX_INITIALIZER; - -static const int DEFAULT_ONE_QUOTA = 2610; -static const int DEFAULT_QUOTA = 5; -static const int PROCESS_HASH_OFFSET = 24; -static const int PROCESS_HASH_NUM = 8; -static const int PROCESS_HASH_NAME_BEGIN_POS = 2; -static const int PROCESS_HASH_NAME_LEN = 8; -static const int LOG_FLOWCTRL_QUOTA_STR_LEN = 2; -static const int LOG_FLOWCTRL_LIST_NUM = 3; -static const int LOG_LEVEL_LEN = 2; -static const int PROP_SWITCH_LEN = 6; using PropertyCache = struct { const void* pinfo; @@ -65,6 +51,16 @@ using PropertyCache = struct { char propertyValue[HILOG_PROP_VALUE_MAX]; }; +using SwitchCache = struct { + PropertyCache cache; + bool isOn; +}; + +using LogLevelCache = struct { + PropertyCache cache; + uint16_t logLevel; +}; + using ProcessInfo = struct { PropertyCache cache; std::string propertyKey; @@ -92,466 +88,308 @@ void PropertyGet(const std::string &key, char *value, int len) void PropertySet(const std::string &key, const char* value) { +/* use OHOS interface */ } -static const char* GetProgName() +std::string GetProgName() { return nullptr; /* use HOS interface */ } -static void RefreshCacheBuf(PropertyCache *cache, const char *key) -{ -} -static bool CheckCache(const PropertyCache *cache) +std::string GetPropertyName(uint32_t propType) { - return true; + std::string key; + switch (propType) { + case PROP_PRIVATE: + key = "hilog.private.on"; + break; + case PROP_PROCESS_FLOWCTRL: + key = "hilog.flowctrl.pid.on"; + break; + case PROP_DOMAIN_FLOWCTRL: + key = "hilog.flowctrl.domain.on"; + break; + case PROP_GLOBAL_LOG_LEVEL: + key = "hilog.loggable.global"; + break; + case PROP_DOMAIN_LOG_LEVEL: + key = "hilog.loggable.domain."; + break; + case PROP_TAG_LOG_LEVEL: + key = "hilog.loggable.tag."; + break; + case PROP_SINGLE_DEBUG: + key = "hilog.debug.on"; + break; + case PROP_PERSIST_DEBUG: + key = "persist.sys.hilog.debug.on"; + break; + default: + break; + } + return key; } -static unsigned int GetHashValue(const char *buf, unsigned int len) +static int LockByProp(uint32_t propType) { - unsigned int crc32 = 0; - int i; - while (len-- != 0) { - crc32 ^= ((*buf++) << PROCESS_HASH_OFFSET); - for (i = 0; i < PROCESS_HASH_NUM; i++) { - if (crc32 & 0x80000000) { - crc32 <<= 1; - crc32 ^= 0x04C11DB7; - } else { - crc32 <<= 1; - } - } + switch (propType) { + case PROP_PRIVATE: + return pthread_mutex_trylock(&g_privateLock); + case PROP_PROCESS_FLOWCTRL: + return pthread_mutex_trylock(&g_processFlowLock); + case PROP_DOMAIN_FLOWCTRL: + return pthread_mutex_trylock(&g_domainFlowLock); + case PROP_GLOBAL_LOG_LEVEL: + return pthread_mutex_trylock(&g_globalLevelLock); + case PROP_DOMAIN_LOG_LEVEL: + return pthread_mutex_trylock(&g_domainLevelLock); + case PROP_TAG_LOG_LEVEL: + return pthread_mutex_trylock(&g_tagLevelLock); + case PROP_SINGLE_DEBUG: + return pthread_mutex_trylock(&g_debugLock); + case PROP_PERSIST_DEBUG: + return pthread_mutex_trylock(&g_persistDebugLock); + default: + return -1; } - return crc32; } -static void UnsignedToHex(unsigned int value, std::string &hexStr) +static void UnlockByProp(uint32_t propType) { - std::stringstream buffer; - buffer.setf(std::ios::hex, std::ios::basefield); - buffer.setf(std::ios::showbase); - buffer << std::hex << value; - buffer >> hexStr; + switch (propType) { + case PROP_PRIVATE: + pthread_mutex_unlock(&g_privateLock); + break; + case PROP_PROCESS_FLOWCTRL: + pthread_mutex_unlock(&g_processFlowLock); + break; + case PROP_DOMAIN_FLOWCTRL: + pthread_mutex_unlock(&g_domainFlowLock); + break; + case PROP_GLOBAL_LOG_LEVEL: + pthread_mutex_unlock(&g_globalLevelLock); + break; + case PROP_DOMAIN_LOG_LEVEL: + pthread_mutex_unlock(&g_domainLevelLock); + break; + case PROP_TAG_LOG_LEVEL: + pthread_mutex_unlock(&g_tagLevelLock); + break; + case PROP_SINGLE_DEBUG: + pthread_mutex_unlock(&g_debugLock); + break; + case PROP_PERSIST_DEBUG: + pthread_mutex_unlock(&g_persistDebugLock); + break; + default: + break; + } } -static std::string GetProcessHashName(const char *processNameStr) +static void RefreshCacheBuf(PropertyCache *cache, const char *key) { - std::string result; - - if (processNameStr == nullptr) { - return result; - } - - unsigned int processNameLen = strlen(processNameStr); - unsigned int crc = GetHashValue(processNameStr, processNameLen); - std::string tmp; - UnsignedToHex(crc, tmp); - std::size_t len = tmp.length(); - if ((len <= PROCESS_HASH_NAME_BEGIN_POS) - || (len > PROCESS_HASH_NAME_BEGIN_POS + PROCESS_HASH_NAME_LEN)) { - return result; - } else if (len < PROCESS_HASH_NAME_BEGIN_POS + PROCESS_HASH_NAME_LEN) { - tmp.insert(PROCESS_HASH_NAME_BEGIN_POS, PROCESS_HASH_NAME_BEGIN_POS + PROCESS_HASH_NAME_LEN - len, '0'); - } - - result = tmp.substr(PROCESS_HASH_NAME_BEGIN_POS, PROCESS_HASH_NAME_LEN); - return result; +/* use OHOS interface */ } -bool IsDebugOn() +static bool CheckCache(const PropertyCache *cache) { - return IsSingleDebugOn() || IsPersistDebugOn(); + return true; +/* use OHOS interface */ } -bool IsSingleDebugOn() +static bool GetSwitchCache(bool isFirst, SwitchCache& switchCache, uint32_t propType, bool defaultValue) { - static PropertyCache switchCache = {nullptr, 0xffffffff, ""}; - static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; - char ctrlSwitch[PROP_SWITCH_LEN] = {0}; int notLocked; - std::string key = "hilog.debug.on"; + std::string key = GetPropertyName(propType); - if (!isFirstFlag.test_and_set() || CheckCache(&switchCache)) { - notLocked = PropLock(&g_debugLock); + if (isFirst || CheckCache(&switchCache.cache)) { + notLocked = LockByProp(propType); if (!notLocked) { - RefreshCacheBuf(&switchCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - PropUnlock(&g_debugLock); - return false; + RefreshCacheBuf(&switchCache.cache, key.c_str()); + if (strcmp(switchCache.cache.propertyValue, "true") == 0) { + switchCache.isOn = true; + } else if (strcmp(switchCache.cache.propertyValue, "false") == 0) { + switchCache.isOn = false; + } else { + switchCache.isOn = defaultValue; } - PropUnlock(&g_debugLock); + UnlockByProp(propType); + return switchCache.isOn; } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, tmpCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; + SwitchCache tmpCache = {{nullptr, 0xffffffff, ""}, defaultValue}; + RefreshCacheBuf(&tmpCache.cache, key.c_str()); + if (strcmp(tmpCache.cache.propertyValue, "true") == 0) { + tmpCache.isOn = true; + } else if (strcmp(tmpCache.cache.propertyValue, "false") == 0) { + tmpCache.isOn = false; + } else { + tmpCache.isOn = defaultValue; } + return tmpCache.isOn; } } else { - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } + return switchCache.isOn; } +} - std::string result = ctrlSwitch; - return result == "true"; +bool IsDebugOn() +{ + return IsSingleDebugOn() || IsPersistDebugOn(); } -bool IsPersistDebugOn() +bool IsSingleDebugOn() { - static PropertyCache switchCache = {nullptr, 0xffffffff, ""}; + static SwitchCache switchCache = {{nullptr, 0xffffffff, ""}, false}; static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; - char ctrlSwitch[PROP_SWITCH_LEN] = {0}; - int notLocked; - std::string key = "persist.sys.hilog.debug.on"; - - if (!isFirstFlag.test_and_set() || CheckCache(&switchCache)) { - notLocked = PropLock(&g_persistDebugLock); - if (!notLocked) { - RefreshCacheBuf(&switchCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - PropUnlock(&g_persistDebugLock); - return false; - } - PropUnlock(&g_persistDebugLock); - } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, tmpCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - } else { - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - - std::string result = ctrlSwitch; - return result == "true"; + bool isFirst = !isFirstFlag.test_and_set(); + return GetSwitchCache(isFirst, switchCache, PROP_SINGLE_DEBUG, false); } - -bool IsPrivateSwitchOn() +bool IsPersistDebugOn() { - static PropertyCache switchCache = {nullptr, 0xffffffff, ""}; + static SwitchCache switchCache = {{nullptr, 0xffffffff, ""}, false}; static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; - char ctrlSwitch[PROP_SWITCH_LEN] = {0}; - int notLocked; - std::string key = "hilog.private.on"; - - if (!isFirstFlag.test_and_set() || CheckCache(&switchCache)) { - notLocked = PropLock(&g_privateLock); - if (!notLocked) { - RefreshCacheBuf(&switchCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - PropUnlock(&g_privateLock); - return false; - } - PropUnlock(&g_privateLock); - } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, tmpCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - } else { - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - - std::string result = ctrlSwitch; - return (result == "false") ? false : true; + bool isFirst = !isFirstFlag.test_and_set(); + return GetSwitchCache(isFirst, switchCache, PROP_PERSIST_DEBUG, false); } -bool IsProcessSwitchOn() +bool IsPrivateSwitchOn() { - static PropertyCache switchCache = {nullptr, 0xffffffff, ""}; + static SwitchCache switchCache = {{nullptr, 0xffffffff, ""}, true}; static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; - char ctrlSwitch[PROP_SWITCH_LEN]; - int notLocked; - std::string key = "hilog.flowctrl.pid"; - - if (!isFirstFlag.test_and_set() || CheckCache(&switchCache)) { - notLocked = PropLock(&g_processFlowLock); - if (!notLocked) { - RefreshCacheBuf(&switchCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - PropUnlock(&g_processFlowLock); - return false; - } - PropUnlock(&g_processFlowLock); - } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, tmpCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - } else { - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - - std::string result = ctrlSwitch; - return result == "on"; + bool isFirst = !isFirstFlag.test_and_set(); + return GetSwitchCache(isFirst, switchCache, PROP_PRIVATE, true); } -bool IsDomainSwitchOn() +bool IsProcessSwitchOn() { - static PropertyCache switchCache = {nullptr, 0xffffffff, ""}; + static SwitchCache switchCache = {{nullptr, 0xffffffff, ""}, false}; static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; - char ctrlSwitch[PROP_SWITCH_LEN]; - int notLocked; - std::string key = "hilog.flowctrl.domain"; - - if (!isFirstFlag.test_and_set() || CheckCache(&switchCache)) { - notLocked = PropLock(&g_domainFlowLock); - if (!notLocked) { - RefreshCacheBuf(&switchCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - PropUnlock(&g_domainFlowLock); - return false; - } - PropUnlock(&g_domainFlowLock); - } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, tmpCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - } else { - if (strncpy_s(ctrlSwitch, PROP_SWITCH_LEN, switchCache.propertyValue, PROP_SWITCH_LEN - 1) != EOK) { - return false; - } - } - - std::string result = ctrlSwitch; - return result == "on"; + bool isFirst = !isFirstFlag.test_and_set(); + return GetSwitchCache(isFirst, switchCache, PROP_PROCESS_FLOWCTRL, false); } -int32_t GetProcessQuota() +bool IsDomainSwitchOn() { + static SwitchCache switchCache = {{nullptr, 0xffffffff, ""}, false}; static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; - char propertyValue[HILOG_PROP_VALUE_MAX]; - const char* quotaPos = nullptr; - int i; - uint32_t processQuota; - int notLocked; - static bool isFirst = true; - static ProcessInfo processInfo = {{nullptr, 0xffffffff, ""}, "", "", "", 0}; - - if (isFirst) { - isFirst = false; - const char* processName = GetProgName(); - processInfo.process = processName; - processInfo.processHashPre = GetProcessHashName(processName).c_str(); - } - - if (!isFirstFlag.test_and_set() || CheckCache(&processInfo.cache)) { - for (i = 0; i < LOG_FLOWCTRL_LIST_NUM; i++) { - std::string propertyKey = "hilog.flowctrl." + std::to_string(i); - PropertyGet(propertyKey, propertyValue, HILOG_PROP_VALUE_MAX); - quotaPos = strstr(propertyValue, (processInfo.processHashPre).c_str()); - if (quotaPos) { - char quotaValueStr[LOG_FLOWCTRL_QUOTA_STR_LEN] = {""}; - if (strncpy_s(quotaValueStr, LOG_FLOWCTRL_QUOTA_STR_LEN, quotaPos + PROCESS_HASH_NAME_LEN, 1) != EOK) { - processInfo.processQuota = DEFAULT_QUOTA; - return DEFAULT_ONE_QUOTA * DEFAULT_QUOTA; - } - if (sscanf_s(quotaValueStr, "%x", &processQuota) <= 0) { - processInfo.processQuota = DEFAULT_QUOTA; - return DEFAULT_ONE_QUOTA * DEFAULT_QUOTA; - } - std::cout << processQuota << std::endl; - notLocked = PropLock(&g_processQuotaLock); - if (!notLocked) { - processInfo.processQuota = processQuota; - processInfo.propertyKey = propertyKey; - RefreshCacheBuf(&processInfo.cache, processInfo.propertyKey.c_str()); - } - break; - } - } - if (!quotaPos) { - notLocked = PropLock(&g_processQuotaLock); - if (!notLocked) { - processInfo.propertyKey = ""; - processInfo.processQuota = DEFAULT_QUOTA; - } - processQuota = DEFAULT_QUOTA; - } - if (!notLocked) { - PropUnlock(&g_processQuotaLock); - } - } else { - processQuota = processInfo.processQuota; - } - return DEFAULT_ONE_QUOTA * processQuota; + bool isFirst = !isFirstFlag.test_and_set(); + return GetSwitchCache(isFirst, switchCache, PROP_DOMAIN_FLOWCTRL, false); } -static uint16_t GetGlobalLevel() +uint16_t GetGlobalLevel() { - std::string key = "hilog.loggable.global"; - static PropertyCache levelCache = {nullptr, 0xffffffff, ""}; - uint16_t logLevel; + std::string key = GetPropertyName(PROP_GLOBAL_LOG_LEVEL); + static LogLevelCache levelCache = {{nullptr, 0xffffffff, ""}, HILOG_LEVEL_MIN}; static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; - char level[LOG_LEVEL_LEN]; int notLocked; - if (!isFirstFlag.test_and_set() || CheckCache(&levelCache)) { + if (!isFirstFlag.test_and_set() || CheckCache(&levelCache.cache)) { notLocked = PropLock(&g_globalLevelLock); if (!notLocked) { - RefreshCacheBuf(&levelCache, key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, levelCache.propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + RefreshCacheBuf(&levelCache.cache, key.c_str()); + if (sscanf_s(levelCache.cache.propertyValue, "%d", &levelCache.logLevel) <= 0) { PropUnlock(&g_globalLevelLock); return HILOG_LEVEL_MIN; } PropUnlock(&g_globalLevelLock); + return levelCache.logLevel; } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, tmpCache.propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + LogLevelCache tmpCache = {{nullptr, 0xffffffff, ""}, HILOG_LEVEL_MIN}; + RefreshCacheBuf(&tmpCache.cache, key.c_str()); + if (sscanf_s(tmpCache.cache.propertyValue, "%d", &tmpCache.logLevel) <= 0) { return HILOG_LEVEL_MIN; } + return tmpCache.logLevel; } } else { - if (strncpy_s(level, LOG_LEVEL_LEN, levelCache.propertyValue, LOG_LEVEL_LEN - 1) != EOK) { - return HILOG_LEVEL_MIN; - } - } - - if (sscanf_s(level, "%x", &logLevel) <= 0) { - return HILOG_LEVEL_MIN; + return levelCache.logLevel; } - - return logLevel; } -static uint16_t GetDomainLevel(uint32_t domain) +uint16_t GetDomainLevel(uint32_t domain) { - static std::unordered_map domainMap; - std::unordered_map::iterator it; - std::string key = "hilog.loggable.domain." + std::to_string(domain); - char level[LOG_LEVEL_LEN]; - uint16_t logLevel; + static std::unordered_map domainMap; + std::unordered_map::iterator it; + std::string key = GetPropertyName(PROP_DOMAIN_LOG_LEVEL) + std::to_string(domain); int notLocked; it = domainMap.find(domain); - if (it == domainMap.end()) { - std::unique_ptr levelCache = std::make_unique(); - levelCache->pinfo = nullptr; - levelCache->serial = 0xffffffff; - RefreshCacheBuf(levelCache.get(), key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, levelCache->propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + if (it == domainMap.end()) { // new domain + LogLevelCache* levelCache = new(LogLevelCache); + levelCache->cache.pinfo = nullptr; + levelCache->cache.serial = 0xffffffff; + RefreshCacheBuf(&levelCache->cache, key.c_str()); + if (sscanf_s(levelCache->cache.propertyValue, "%d", &levelCache->logLevel) <= 0) { return HILOG_LEVEL_MIN; } - domainMap.insert(std::make_pair(domain, levelCache.get())); - } else { - if (CheckCache(it->second)) { + domainMap.insert({ domain, levelCache }); + return levelCache->logLevel; + } else { // exist domain + if (CheckCache(&it->second->cache)) { // change notLocked = PropLock(&g_domainLevelLock); if (!notLocked) { - RefreshCacheBuf(it->second, key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, it->second->propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + RefreshCacheBuf(&it->second->cache, key.c_str()); + if (sscanf_s(it->second->cache.propertyValue, "%d", &it->second->logLevel) <= 0) { PropUnlock(&g_domainLevelLock); return HILOG_LEVEL_MIN; } PropUnlock(&g_domainLevelLock); + return it->second->logLevel; } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, tmpCache.propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + LogLevelCache tmpCache = {{nullptr, 0xffffffff, ""}, HILOG_LEVEL_MIN}; + RefreshCacheBuf(&tmpCache.cache, key.c_str()); + if (sscanf_s(tmpCache.cache.propertyValue, "%d", &tmpCache.logLevel) <= 0) { return HILOG_LEVEL_MIN; } - } - } else { - if (strncpy_s(level, LOG_LEVEL_LEN, it->second->propertyValue, LOG_LEVEL_LEN - 1) != EOK) { - return HILOG_LEVEL_MIN; - } - } + return tmpCache.logLevel; + } + } else { // not change + return it->second->logLevel; + } } - - if (sscanf_s(level, "%x", &logLevel) <= 0) { - return HILOG_LEVEL_MIN; - } - - return logLevel; } -static uint16_t GetTagLevel(const char* tag) +uint16_t GetTagLevel(const std::string& tag) { - static std::unordered_map tagMap; - std::unordered_map::iterator it; + static std::unordered_map tagMap; + std::unordered_map::iterator it; std::string tagStr = tag; - std::string key = "hilog.loggable.tag." + tagStr; - uint32_t logLevel; - char level[LOG_LEVEL_LEN]; + std::string key = GetPropertyName(PROP_TAG_LOG_LEVEL) + tagStr; int notLocked; it = tagMap.find(tagStr); if (it == tagMap.end()) { - std::unique_ptr levelCache = std::make_unique(); - levelCache->pinfo = nullptr; - levelCache->serial = 0xffffffff; - RefreshCacheBuf(levelCache.get(), key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, levelCache->propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + LogLevelCache* levelCache = new(LogLevelCache); + levelCache->cache.pinfo = nullptr; + levelCache->cache.serial = 0xffffffff; + RefreshCacheBuf(&levelCache->cache, key.c_str()); + if (sscanf_s(levelCache->cache.propertyValue, "%d", &levelCache->logLevel) <= 0) { return HILOG_LEVEL_MIN; } - tagMap.insert(std::make_pair(tagStr, levelCache.get())); + tagMap.insert({ tagStr, levelCache }); + return levelCache->logLevel; } else { - if (CheckCache(it->second)) { + if (CheckCache(&it->second->cache)) { notLocked = PropLock(&g_tagLevelLock); if (!notLocked) { - RefreshCacheBuf(it->second, key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, it->second->propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + RefreshCacheBuf(&it->second->cache, key.c_str()); + if (sscanf_s(it->second->cache.propertyValue, "%d", &it->second->logLevel) <= 0) { PropUnlock(&g_tagLevelLock); return HILOG_LEVEL_MIN; } PropUnlock(&g_tagLevelLock); + return it->second->logLevel; } else { - PropertyCache tmpCache = {nullptr, 0xffffffff, ""}; - RefreshCacheBuf(&tmpCache, key.c_str()); - if (strncpy_s(level, LOG_LEVEL_LEN, tmpCache.propertyValue, LOG_LEVEL_LEN - 1) != EOK) { + LogLevelCache tmpCache = {{nullptr, 0xffffffff, ""}, HILOG_LEVEL_MIN}; + RefreshCacheBuf(&tmpCache.cache, key.c_str()); + if (sscanf_s(tmpCache.cache.propertyValue, "%d", &tmpCache.logLevel) <= 0) { return HILOG_LEVEL_MIN; } + return tmpCache.logLevel; } } else { - if (strncpy_s(level, LOG_LEVEL_LEN, it->second->propertyValue, LOG_LEVEL_LEN - 1) != EOK) { - return HILOG_LEVEL_MIN; - } + return it->second->logLevel; } - } - - if (sscanf_s(level, "%x", &logLevel) <= 0) { - return HILOG_LEVEL_MIN; - } - - return logLevel; -} - -static uint16_t GetFinalLevel(unsigned int domain, const char *tag) -{ - uint16_t domainLevel = GetDomainLevel(domain); - uint16_t tagLevel = GetTagLevel(tag); - uint16_t globalLevel = GetGlobalLevel(); - uint16_t maxLevel = HILOG_LEVEL_MIN; - maxLevel = (maxLevel < domainLevel) ? domainLevel : maxLevel; - maxLevel = (maxLevel < tagLevel) ? tagLevel : maxLevel; - maxLevel = (maxLevel < globalLevel) ? globalLevel : maxLevel; - return maxLevel; -} - -bool IsLevelLoggable(unsigned int domain, const char *tag, uint16_t level) -{ - if ((level <= HILOG_LEVEL_MIN) || (level >= HILOG_LEVEL_MAX) || tag == nullptr) { - return false; - } - if (level < GetFinalLevel(domain, tag)) { - return false; - } - return true; + } } diff --git a/adapter/properties.h b/adapter/properties.h index de5434c14c1a272dfd620a4601bd238f754a1275..cebbaa193af0ecdd55d7bffdbf5d18deefea87d0 100644 --- a/adapter/properties.h +++ b/adapter/properties.h @@ -22,9 +22,20 @@ static const int HILOG_PROP_VALUE_MAX = 92; -#ifdef __cplusplus -extern "C" { -#endif +using PropType = enum { + PROP_PRIVATE = 0x01, + PROP_PROCESS_FLOWCTRL, + PROP_DOMAIN_FLOWCTRL, + PROP_GLOBAL_LOG_LEVEL, + PROP_DOMAIN_LOG_LEVEL, + PROP_TAG_LOG_LEVEL, + PROP_SINGLE_DEBUG, + PROP_PERSIST_DEBUG, +}; + +std::string GetPropertyName(uint32_t propType); +std::string GetProgName(); +uint16_t GetTagLevel(const std::string& tag); void PropertyGet(const std::string &key, char *value, int len); void PropertySet(const std::string &key, const char* value); bool IsDebugOn(); @@ -33,10 +44,7 @@ bool IsPersistDebugOn(); bool IsPrivateSwitchOn(); bool IsProcessSwitchOn(); bool IsDomainSwitchOn(); -bool IsLevelLoggable(unsigned int domain, const char *tag, uint16_t level); -int32_t GetProcessQuota(); -#ifdef __cplusplus -} -#endif -#endif +uint16_t GetGlobalLevel(); +uint16_t GetDomainLevel(uint32_t domain); +#endif diff --git a/frameworks/native/format.cpp b/frameworks/native/format.cpp index 3d80b666ed8ac5a8add79ad6cdb436da2a1ef4e2..591107b1b1b7206e8d8716d87a2b0831416f607d 100644 --- a/frameworks/native/format.cpp +++ b/frameworks/native/format.cpp @@ -58,84 +58,92 @@ int ColorFromLevel(uint16_t level) } } -int HilogShowTimeBuffer(char* buffer, int bufLen, HilogShowFormat showFormat, time_t now, unsigned long nsecTime) -{ - struct tm* ptm = nullptr; +int HilogShowTimeBuffer(char* buffer, int bufLen, HilogShowFormat showFormat, + const HilogShowFormatBuffer& contentOut) +{ + time_t now = contentOut.tv_sec; + unsigned long nsecTime = contentOut.tv_nsec; + struct tm* ptm = nullptr; size_t timeLen = 0; int ret = 0; nsecTime = (now < 0) ? (NS - nsecTime) : nsecTime; - - if ((showFormat == EPOCH_SHOWFORMAT) || (showFormat == MONOTONIC_SHOWFORMAT)) { + + if ((showFormat == EPOCH_SHOWFORMAT) || (showFormat == MONOTONIC_SHOWFORMAT)) { ret = snprintf_s(buffer, bufLen, bufLen - 1, (showFormat == MONOTONIC_SHOWFORMAT) ? "%6lld" : "%19lld", (long long)now); timeLen += ((ret > 0) ? ret : 0); } else { - ptm = localtime(&now); - if (ptm == nullptr) { + ptm = localtime(&now); + if (ptm == nullptr) { return 0; - } + } switch (showFormat) { - case YEAR_SHOWFORMAT: + case YEAR_SHOWFORMAT: timeLen = strftime(buffer, bufLen, "%Y-%m-%d %H:%M:%S", ptm); ret = snprintf_s(buffer + timeLen, bufLen - timeLen, bufLen - timeLen - 1, ".%03llu", nsecTime / NS2MS); timeLen += ((ret > 0) ? ret : 0); - break; - case ZONE_SHOWFORMAT: + break; + case ZONE_SHOWFORMAT: timeLen = strftime(buffer, bufLen, "%z %m-%d %H:%M:%S", ptm); ret = snprintf_s(buffer + timeLen, bufLen - timeLen, bufLen - timeLen - 1, ".%03llu", nsecTime / NS2MS); timeLen += ((ret > 0) ? ret : 0); - break; + break; case TIME_NSEC_SHOWFORMAT: timeLen = strftime(buffer, bufLen, "%m-%d %H:%M:%S", ptm); ret = snprintf_s(buffer + timeLen, bufLen - timeLen, bufLen - timeLen - 1, ".%09ld", nsecTime); timeLen += ((ret > 0) ? ret : 0); - break; - case TIME_USEC_SHOWFORMAT: + break; + case TIME_USEC_SHOWFORMAT: timeLen = strftime(buffer, bufLen, "%m-%d %H:%M:%S", ptm); ret = snprintf_s(buffer + timeLen, bufLen - timeLen, bufLen - timeLen - 1, ".%06llu", nsecTime / NS2US); timeLen += ((ret > 0) ? ret : 0); break; - default: + case COLOR_SHOWFORMAT: + ret = snprintf_s(buffer, bufLen, bufLen, + "\x1B[38;5;%dm%02d-%02d %02d:%02d:%02d.%03llu\x1b[0m", ColorFromLevel(contentOut.level), + ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, nsecTime / NS2MS); + timeLen += ((ret > 0) ? ret : 0); + break; + default: timeLen = strftime(buffer, bufLen, "%m-%d %H:%M:%S", ptm); ret = snprintf_s(buffer + timeLen, bufLen - timeLen, bufLen - timeLen - 1, ".%03llu", nsecTime / NS2MS); timeLen += ((ret > 0) ? ret : 0); break; - } - } - - return timeLen; + } + } + return timeLen; } void HilogShowBuffer(char* buffer, int bufLen, const HilogShowFormatBuffer& contentOut, HilogShowFormat showFormat) { int logLen = 0; int ret = 0; - if (buffer == nullptr) { return; } - logLen += HilogShowTimeBuffer(buffer, bufLen, showFormat, (time_t)contentOut.tv_sec, contentOut.tv_nsec); - + logLen += HilogShowTimeBuffer(buffer, bufLen, showFormat, contentOut); + if (showFormat == COLOR_SHOWFORMAT) { ret = snprintf_s(buffer + logLen, bufLen - logLen, bufLen - logLen - 1, - " \x1B[38;5;%dm%5d", ColorFromLevel(contentOut.level), contentOut.pid); + " \x1B[38;5;%dm%5d\x1b[0m", ColorFromLevel(contentOut.level), contentOut.pid); logLen += ((ret > 0) ? ret : 0); ret = snprintf_s(buffer + logLen, bufLen - logLen, bufLen - logLen - 1, - " \x1B[38;5;%dm%5d", ColorFromLevel(contentOut.level), contentOut.tid); + " \x1B[38;5;%dm%5d\x1b[0m", ColorFromLevel(contentOut.level), contentOut.tid); logLen += ((ret > 0) ? ret : 0); ret = snprintf_s(buffer + logLen, bufLen - logLen, bufLen - logLen - 1, - " \x1B[38;5;%dm%s ", ColorFromLevel(contentOut.level), ParsedFromLevel(contentOut.level)); + " \x1B[38;5;%dm%s \x1b[0m", ColorFromLevel(contentOut.level), ParsedFromLevel(contentOut.level)); logLen += ((ret > 0) ? ret : 0); ret = snprintf_s(buffer + logLen, bufLen - logLen, bufLen - logLen - 1, - "\x1B[38;5;%dm%05x/%s:", ColorFromLevel(contentOut.level), contentOut.domain & 0xFFFFF, contentOut.data); + "\x1B[38;5;%dm%05x/%s:\x1b[0m", ColorFromLevel(contentOut.level), + contentOut.domain & 0xFFFFF, contentOut.data); logLen += ((ret > 0) ? ret : 0); ret = snprintf_s(buffer + logLen, bufLen - logLen, bufLen - logLen - 1, - " \x1B[38;5;%dm%s", ColorFromLevel(contentOut.level), contentOut.data + contentOut.tag_len); + " \x1B[38;5;%dm%s\x1b[0m", ColorFromLevel(contentOut.level), contentOut.data + contentOut.tag_len); logLen += ((ret > 0) ? ret : 0); } else { ret = snprintf_s(buffer + logLen, bufLen - logLen, bufLen - logLen - 1, @@ -152,8 +160,8 @@ void HilogShowBuffer(char* buffer, int bufLen, const HilogShowFormatBuffer& cont logLen += ((ret > 0) ? ret : 0); ret = snprintf_s(buffer + logLen, bufLen - logLen, bufLen - logLen - 1, " %s", contentOut.data + contentOut.tag_len); - logLen += ((ret > 0) ? ret : 0); - } -} + logLen += ((ret > 0) ? ret : 0); + } } } +} \ No newline at end of file diff --git a/frameworks/native/hilog_printf.cpp b/frameworks/native/hilog_printf.cpp index 9e9ef2828f549ee2d6012095e42936ed2882df8f..81e291f4506f217ca7100d08636dc32792fe5739 100644 --- a/frameworks/native/hilog_printf.cpp +++ b/frameworks/native/hilog_printf.cpp @@ -13,9 +13,11 @@ * limitations under the License. */ +#include "properties.h" #include #include +#include #include #include #include @@ -23,13 +25,11 @@ #include #include -#include "properties.h" #include "hilog_trace.h" #include "hilog_inner.h" #include "hilog/log.h" #include "hilog_common.h" #include "hilog_input_socket_client.h" -#include "properties.h" using namespace std; static RegisterFunc g_registerFunc = nullptr; @@ -39,7 +39,8 @@ static const char P_LIMIT_TAG[] = "LOGLIMITP"; #ifdef DEBUG static const int MAX_PATH_LEN = 1024; #endif - +static const int DEFAULT_QUOTA = 13050; +static const int LOG_FLOWCTRL_QUOTA_STR_LEN = 6; int HiLogRegisterGetIdFun(RegisterFunc registerFunc) { if (g_registerFunc != nullptr) { @@ -70,27 +71,79 @@ static long long HiLogTimespecSub(struct timespec a, struct timespec b) ret -= NSEC_PER_SEC * a.tv_sec + a.tv_nsec; return ret; } +static uint16_t GetFinalLevel(unsigned int domain, const std::string& tag) +{ + uint16_t domainLevel = GetDomainLevel(domain); + uint16_t tagLevel = GetTagLevel(tag); + uint16_t globalLevel = GetGlobalLevel(); + uint16_t maxLevel = LOG_LEVEL_MIN; + maxLevel = (maxLevel < domainLevel) ? domainLevel : maxLevel; + maxLevel = (maxLevel < tagLevel) ? tagLevel : maxLevel; + maxLevel = (maxLevel < globalLevel) ? globalLevel : maxLevel; + return maxLevel; +} +static uint32_t ParseProcessQuota() +{ + uint32_t proQuota = DEFAULT_QUOTA; + std::string proName = GetProgName(); + static constexpr char flowCtrlQuotaFile[] = "/system/etc/hilog_flowcontrol_quota.conf"; + std::ifstream ifs(flowCtrlQuotaFile, std::ifstream::in); + if (!ifs.is_open()) { + return proQuota; + } + std::string line; + while (!ifs.eof()) { + getline(ifs, line); + if (line.empty() || line.at(0) == '#') { + continue; + } + std::string processName; + std::string processQuotaValue; + std::size_t processNameEnd = line.find_first_of(" "); + if (processNameEnd == std::string::npos) { + continue; + } + processName = line.substr(0, processNameEnd); + if (++processNameEnd >= line.size()) { + continue; + } + if (proName == processName) { + processQuotaValue = line.substr(processNameEnd, LOG_FLOWCTRL_QUOTA_STR_LEN); + char quotaValue[LOG_FLOWCTRL_QUOTA_STR_LEN]; + strcpy_s(quotaValue, LOG_FLOWCTRL_QUOTA_STR_LEN, processQuotaValue.c_str()); + sscanf_s(quotaValue, "%d", &proQuota); + ifs.close(); + return proQuota; + } + } + ifs.close(); + return proQuota; +} static int HiLogFlowCtrlProcess(int len, uint16_t logType, bool debug) { if (logType == LOG_APP || !IsProcessSwitchOn() || debug) { return 0; } + static uint32_t processQuota = DEFAULT_QUOTA; static atomic_int gSumLen = 0; static atomic_int gDropped = 0; static atomic gStartTime = atomic({ .tv_sec = 0, .tv_nsec = 0 }); + static std::atomic_flag isFirstFlag = ATOMIC_FLAG_INIT; + if (!isFirstFlag.test_and_set()) { + processQuota = ParseProcessQuota(); + } + struct timespec tsNow = { 0, 0 }; struct timespec tsStart = atomic_load(&gStartTime); - clock_gettime(CLOCK_REALTIME, &tsNow); - + clock_gettime(CLOCK_MONOTONIC, &tsNow); long long ns = HiLogTimespecSub(tsStart, tsNow); /* in statistic period(1 second) */ if (ns <= NSEC_PER_SEC) { uint32_t sumLen = (uint32_t)atomic_load(&gSumLen); - uint32_t processQuota = GetProcessQuota(); if (sumLen > processQuota) { /* over quota, -1 means don't print */ atomic_fetch_add_explicit(&gDropped, 1, memory_order_relaxed); return -1; @@ -224,5 +277,11 @@ int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *ta bool HiLogIsLoggable(unsigned int domain, const char *tag, LogLevel level) { + if ((level <= LOG_LEVEL_MIN) || (level >= LOG_LEVEL_MAX) || tag == nullptr) { + return false; + } + if (level < GetFinalLevel(domain, tag)) { + return false; + } return true; } diff --git a/frameworks/native/include/hilogtool_msg.h b/frameworks/native/include/hilogtool_msg.h index 65bffffa707806bcbed46acb41a470dd9b0b012b..cd4b03c68ef58b5a2d7568aa0f7d0e97ef1f3fb6 100644 --- a/frameworks/native/include/hilogtool_msg.h +++ b/frameworks/native/include/hilogtool_msg.h @@ -22,9 +22,7 @@ #include #include "hilog_common.h" -#define DOMAIN_MAX_LEN 11 -#define FILE_PATH_MAX_LEN 1024 -#define JOB_ID_MAX_LEN 10 +#define FILE_PATH_MAX_LEN 100 typedef enum { LOG_QUERY_REQUEST = 0x01, @@ -59,7 +57,6 @@ typedef enum { OT_PRIVATE_SWITCH = 0x01, OT_LOG_LEVEL, OT_FLOW_SWITCH, - OT_FLOW_QUOTA, } OperateType; typedef enum { @@ -251,7 +248,7 @@ typedef struct { char filePath[FILE_PATH_MAX_LEN]; uint32_t fileSize; uint32_t fileNum; - char jobId[JOB_ID_MAX_LEN]; + uint32_t jobId; } LogPersistStartMsg; typedef struct { MessageHeader msgHeader; @@ -260,7 +257,7 @@ typedef struct { typedef struct { int32_t result; - char jobId[JOB_ID_MAX_LEN]; + uint32_t jobId; } LogPersistStartResult; typedef struct { @@ -269,7 +266,7 @@ typedef struct { } LogPersistStartResponse; typedef struct { - char jobId[JOB_ID_MAX_LEN]; + uint32_t jobId; } LogPersistStopMsg; typedef struct { MessageHeader msgHeader; @@ -278,7 +275,7 @@ typedef struct { typedef struct { int32_t result; - char jobId[JOB_ID_MAX_LEN]; + uint32_t jobId; } LogPersistStopResult; typedef struct { MessageHeader msgHeader; @@ -290,12 +287,12 @@ typedef struct { } LogPersistQueryMsg; typedef struct { MessageHeader msgHeader; - LogPersistQueryMsg logPersistQueryMsg[]; + LogPersistQueryMsg logPersistQueryMsg; } LogPersistQueryRequest; typedef struct { int32_t result; - char jobId[JOB_ID_MAX_LEN]; + uint32_t jobId; uint16_t logType; uint16_t compressType; uint16_t compressAlg; @@ -315,28 +312,8 @@ typedef struct { std::string domainStr; std::string tagStr; std::string pidStr; - std::string flowQuotaStr; } SetPropertyParam; -typedef struct { - char domain[DOMAIN_MAX_LEN]; - uint32_t flowQuota; -} FlowCtrlMsg; -typedef struct { - MessageHeader msgHeader; - FlowCtrlMsg flowCtrlMsg[]; -} FlowCtrlRequest; - -typedef struct { - char domain[DOMAIN_MAX_LEN]; - uint32_t flowQuota; -} FlowCtrlResult; - -typedef struct { - MessageHeader msgHeader; - int32_t result; - FlowCtrlResult flowCtrlRst[]; -} FlowCtrlResponse; typedef struct { uint16_t noBlockMode; @@ -370,5 +347,4 @@ typedef struct { std::string algorithmArgs; } HilogArgs; -#endif /* HILOGTOOL_MSG_H */ - +#endif /* HILOGTOOL_MSG_H */ \ No newline at end of file diff --git a/services/hilogd/flow_control_init.cpp b/services/hilogd/flow_control_init.cpp index 74d642c8535216af7a34a7b3b56e919ab46a9ca9..1b7729302d9cedd3bb0d687d520ddfdc537eb62d 100644 --- a/services/hilogd/flow_control_init.cpp +++ b/services/hilogd/flow_control_init.cpp @@ -29,7 +29,6 @@ namespace OHOS { namespace HiviewDFX { static const int DOMAIN_FILTER = 0x00fffff; static const int DOMAIN_FILTER_SUBSYSTEM = 8; -static const int SINGLE_PROCESS_VALUE_LEN = 9; static const long long NSEC_PER_SEC = 1000000000LL; using DomainInfo = struct { @@ -41,16 +40,6 @@ using DomainInfo = struct { struct timespec startTime; }; -namespace { - constexpr char FIRST_FLOW_CTRL_ATTR_NAME[] = "hilog.flowctrl.1"; - constexpr char SECOND_FLOW_CTRL_ATTR_NAME[] = "hilog.flowctrl.2"; - constexpr char THIRD_FLOW_CTRL_ATTR_NAME[] = "hilog.flowctrl.3"; -} - -static std::string g_firstFlowCtrQuotaValue; -static std::string g_secondFlowCtrQuotaValue; -static std::string g_thirdFlowCtrQuotaValue; - static std::unordered_map g_domainMap; static int32_t g_typeDropped[LOG_TYPE_MAX]; @@ -98,70 +87,6 @@ int32_t GetDroppedByDomain(uint32_t domainId) return 0; } -void ParseProcessQuota(const std::string line) -{ - if (line.empty() || line.at(0) == '#') { - return; - } - std::string processName; - std::string processHashName; - std::string processQuotaValue; - std::size_t processNameEnd = line.find_first_of(" "); - if (processNameEnd == std::string::npos) { - return; - } - processName = line.substr(0, processNameEnd); - if (++processNameEnd >= line.size()) { - return; - } - std::size_t processHashNameEnd = line.find_first_of(" ", processNameEnd); - if (processHashNameEnd == std::string::npos) { - return; - } - processHashName = line.substr(processNameEnd, processHashNameEnd - processNameEnd); - if (++processHashNameEnd >= line.size()) { - return; - } - processQuotaValue = line.substr(processHashNameEnd, 1); - if ((HILOG_PROP_VALUE_MAX - g_firstFlowCtrQuotaValue.length()) / SINGLE_PROCESS_VALUE_LEN > 0) { - g_firstFlowCtrQuotaValue += (processHashName + processQuotaValue); - } else if ((HILOG_PROP_VALUE_MAX - g_secondFlowCtrQuotaValue.length()) / SINGLE_PROCESS_VALUE_LEN > 0) { - g_secondFlowCtrQuotaValue += (processHashName + processQuotaValue); - } else if ((HILOG_PROP_VALUE_MAX - g_thirdFlowCtrQuotaValue.length()) / SINGLE_PROCESS_VALUE_LEN > 0) { - g_thirdFlowCtrQuotaValue += (processHashName + processQuotaValue); - } - - return; -} - - -int32_t InitProcessFlowCtrl() -{ - static constexpr char flowCtrlQuotaFile[] = "/system/etc/hilog_flowcontrol_quota.conf"; - std::ifstream ifs(flowCtrlQuotaFile, std::ifstream::in); - if (!ifs.is_open()) { - return -1; - } - std::string line; - while (!ifs.eof()) { - getline(ifs, line); - ParseProcessQuota(line); - } - ifs.close(); - if (!g_firstFlowCtrQuotaValue.empty()) { - PropertySet(FIRST_FLOW_CTRL_ATTR_NAME, g_firstFlowCtrQuotaValue.c_str()); - } - if (!g_secondFlowCtrQuotaValue.empty()) { - PropertySet(SECOND_FLOW_CTRL_ATTR_NAME, g_secondFlowCtrQuotaValue.c_str()); - } - if (!g_thirdFlowCtrQuotaValue.empty()) { - PropertySet(THIRD_FLOW_CTRL_ATTR_NAME, g_thirdFlowCtrQuotaValue.c_str()); - } - - return 0; -} - - void ParseDomainQuota(std::string &domainStr) { if (domainStr.empty() || domainStr.at(0) == '#') { @@ -254,7 +179,7 @@ int FlowCtrlDomain(HilogMsg* hilogMsg) int ret = 0; it = g_domainMap.find(domainId); if (it != g_domainMap.end()) { - clock_gettime(CLOCK_REALTIME, &tsNow); + clock_gettime(CLOCK_MONOTONIC, &tsNow); /* in statistic period(1 second) */ if (TimespecSub(it->second->startTime, tsNow) < NSEC_PER_SEC) { if (it->second->sumLen <= it->second->domainQuota) { /* under quota */ diff --git a/services/hilogd/include/flow_control_init.h b/services/hilogd/include/flow_control_init.h index d52bad564232ab465d7600a22061b5579fc13f1a..4278202ded0576bc866d9a9ae40be486af83f983 100644 --- a/services/hilogd/include/flow_control_init.h +++ b/services/hilogd/include/flow_control_init.h @@ -20,7 +20,6 @@ namespace OHOS { namespace HiviewDFX { -int32_t InitProcessFlowCtrl(); int32_t InitDomainFlowCtrl(); int FlowCtrlDomain(HilogMsg* hilogMsg); int32_t GetDroppedByType(uint16_t logType); diff --git a/services/hilogd/include/log_buffer.h b/services/hilogd/include/log_buffer.h index f2c5681a0478a4b7e8bdd9af83190081a324fd4c..9318f6798e2fcfa9ebb3ae8c1ce98192d98dc18a 100644 --- a/services/hilogd/include/log_buffer.h +++ b/services/hilogd/include/log_buffer.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "log_reader.h" @@ -33,6 +34,7 @@ public: ~HilogBuffer(); std::vector> logReaderList; + std::shared_mutex logReaderListMutex; size_t Insert(const HilogMsg& msg); bool Query(LogReader* reader); bool Query(std::shared_ptr reader); diff --git a/services/hilogd/include/log_persister.h b/services/hilogd/include/log_persister.h index f3e3fcc5d008cc1aab5a3d94d437fd28c000a01c..1eb4de77f969ff0e992df0e3f140f2dec979dcd5 100644 --- a/services/hilogd/include/log_persister.h +++ b/services/hilogd/include/log_persister.h @@ -37,7 +37,7 @@ const uint16_t MAX_PERSISTER_BUFFER_SIZE = 4096; class LogPersister : public LogReader { public: - LogPersister(std::string name, std::string path, uint16_t compressType, + LogPersister(uint32_t id, std::string path, uint16_t compressType, uint16_t compressAlg, int sleepTime, LogPersisterRotator *rotator, HilogBuffer *buffer); ~LogPersister(); @@ -45,22 +45,22 @@ public: void NotifyForNewData(); int WriteData(HilogData *data); int ThreadFunc(); - static int Kill(const std::string &name); + static int Kill(uint32_t id); void Exit(); static int Query(uint16_t logType, std::list &results); int Init(); - int Start(); - bool Identify(const std::string &name, const std::string &path = ""); + void Start(); + bool Identify(uint32_t id); void FillInfo(LogPersistQueryResult *response); - std::string GetName(); int MkDirPath(const char *p_cMkdir); bool writeUnCompressedBuffer(HilogData *data); uint8_t getType() const; + std::string getPath(); LogPersisterBuffer *buffer; private: - std::string name; + uint32_t id; std::string path; std::string mmapPath; uint16_t compressType; @@ -71,8 +71,10 @@ private: std::mutex mutexForhasExited; std::condition_variable cvhasExited; LogPersisterRotator *rotator; + bool toExit; bool hasExited; inline void WriteFile(); + bool isExited(); FILE *fdinfo; int fd = -1; diff --git a/services/hilogd/include/log_reader.h b/services/hilogd/include/log_reader.h index 508847dac7c997c11b52cabdc4a8c765f2c92525..aed5feb5d07b833b4cad247f9cbd4f7d6f4bf9f1 100644 --- a/services/hilogd/include/log_reader.h +++ b/services/hilogd/include/log_reader.h @@ -43,6 +43,7 @@ using QueryCondition = struct QueryCondition { class LogReader : public std::enable_shared_from_this { public: std::list::iterator readPos; + std::list::iterator lastPos; std::list oldData; QueryCondition queryCondition; std::unique_ptr hilogtoolConnectSocket; @@ -50,8 +51,6 @@ public: LogReader(); virtual ~LogReader(); - bool SetWaitForNewData(bool); - bool GetWaitForNewData() const; bool GetReload() const; void SetReload(bool); virtual void NotifyForNewData() = 0; @@ -67,7 +66,6 @@ protected: static HilogBuffer* hilogBuffer; private: - bool waitForNewData = false; bool isReload = true; }; } // namespace HiviewDFX diff --git a/services/hilogd/log_buffer.cpp b/services/hilogd/log_buffer.cpp index 539d0e42a1dba3c1c775cd0b3be7dca1688a89fd..7fd532709a65a4149ae1ac8ff56456a9cfb77b5f 100644 --- a/services/hilogd/log_buffer.cpp +++ b/services/hilogd/log_buffer.cpp @@ -70,11 +70,16 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) ++it; continue; } + logReaderListMutex.lock_shared(); for (auto &itr :logReaderList) { if (itr.lock()->readPos == it) { itr.lock()->readPos = std::next(it); } + if (itr.lock()->lastPos == it) { + itr.lock()->lastPos = std::next(it); + } } + logReaderListMutex.unlock_shared(); size_t cLen = it->len - it->tag_len; size -= cLen; sizeByType[(*it).type] -= cLen; @@ -97,11 +102,13 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) // Find the place with right timestamp ++rit; for (; rit != hilogDataList.rend() && msg.tv_sec < rit->tv_sec; ++rit) { + logReaderListMutex.lock_shared(); for (auto &itr :logReaderList) { if (itr.lock()->readPos == std::prev(rit.base())) { itr.lock()->oldData.emplace_front(msg); } } + logReaderListMutex.unlock_shared(); } hilogDataList.emplace(rit.base(), msg); hilogBufferMutex.unlock(); @@ -124,11 +131,16 @@ bool HilogBuffer::Query(std::shared_ptr reader) hilogBufferMutex.lock(); if (reader->GetReload()) { reader->readPos = hilogDataList.begin(); + reader->lastPos = hilogDataList.begin(); reader->SetReload(false); } if (reader->isNotified) { - reader->readPos++; + if (reader->lastPos == hilogDataList.end()) { + reader->readPos = std::prev(reader->lastPos); + } else { + reader->readPos = std::next(reader->lastPos); + } } // Look up in oldData first if (!reader->oldData.empty()) { @@ -146,6 +158,7 @@ bool HilogBuffer::Query(std::shared_ptr reader) return true; } while (reader->readPos != hilogDataList.end()) { + reader->lastPos = reader->readPos; if (conditionMatch(reader)) { reader->SetSendId(SENDIDA); reader->WriteData(&*(reader->readPos)); @@ -183,19 +196,17 @@ size_t HilogBuffer::Delete(uint16_t logType) continue; } // Delete corresponding logs + logReaderListMutex.lock_shared(); for (auto itr = logReaderList.begin(); itr != logReaderList.end();) { - if ((*itr).expired()) { -#ifdef DEBUG - cout << "remove expired reader!" << endl; -#endif - itr = logReaderList.erase(itr); - continue; - } if ((*itr).lock()->readPos == it) { - (*itr).lock()->NotifyReload(); + (*itr).lock()->readPos = std::next(it); + } + if ((*itr).lock()->lastPos == it) { + (*itr).lock()->lastPos = std::next(it); } ++itr; } + logReaderListMutex.unlock_shared(); size_t cLen = it->len - it->tag_len; sum += cLen; @@ -210,10 +221,11 @@ size_t HilogBuffer::Delete(uint16_t logType) void HilogBuffer::AddLogReader(std::weak_ptr reader) { - hilogBufferMutex.lock(); + logReaderListMutex.lock(); // If reader not in logReaderList logReaderList.push_back(reader); - hilogBufferMutex.unlock(); + reader.lock()->lastPos = hilogDataList.end(); + logReaderListMutex.unlock(); } bool HilogBuffer::Query(LogReader* reader) @@ -244,11 +256,16 @@ size_t HilogBuffer::SetBuffLen(uint16_t logType, uint64_t buffSize) ++it; continue; } + logReaderListMutex.lock_shared(); for (auto &itr :logReaderList) { if (itr.lock()->readPos == it) { itr.lock()->readPos = std::next(it); } + if (itr.lock()->lastPos == it) { + itr.lock()->lastPos = std::next(it); + } } + logReaderListMutex.unlock_shared(); size_t cLen = it->len - it->tag_len; size -= cLen; sizeByType[(*it).type] -= cLen; @@ -347,8 +364,6 @@ void HilogBuffer::ReturnNoLog(std::shared_ptr reader) { reader->SetSendId(SENDIDN); reader->WriteData(nullptr); - reader->readPos--; - reader->SetWaitForNewData(true); } void HilogBuffer::GetBufferLock() diff --git a/services/hilogd/log_collector.cpp b/services/hilogd/log_collector.cpp index 16496a539b009e22d4c9f9418905c37a0693c402..24290013a5b772112b7016b93e0b06817a071544 100644 --- a/services/hilogd/log_collector.cpp +++ b/services/hilogd/log_collector.cpp @@ -84,23 +84,13 @@ size_t LogCollector::InsertLogToBuffer(const HilogMsg& msg) if (result <= 0) { return result; } - hilogBuffer->GetBufferLock(); + hilogBuffer->logReaderListMutex.lock_shared(); auto it = hilogBuffer->logReaderList.begin(); while (it != hilogBuffer->logReaderList.end()) { - if ((*it).expired()) { - it = hilogBuffer->logReaderList.erase(it); -#ifdef DEBUG - cout << "removed expired reader!" << endl; -#endif - continue; - } - if ((*it).lock()->GetWaitForNewData() && - static_cast((1 << msg.type) & (*it).lock()->queryCondition.types) != 0) { - (*it).lock()->NotifyForNewData(); - } + (*it).lock()->NotifyForNewData(); ++it; } - hilogBuffer->ReleaseBufferLock(); + hilogBuffer->logReaderListMutex.unlock_shared(); return result; } } // namespace HiviewDFX diff --git a/services/hilogd/log_persister.cpp b/services/hilogd/log_persister.cpp index 888d4a4fa2e2a1d529b12c61301df773a0be4e1a..b49a53e41ee70caacd59a495e224c664dba91fac 100644 --- a/services/hilogd/log_persister.cpp +++ b/services/hilogd/log_persister.cpp @@ -67,12 +67,13 @@ string GenPersistLogHeader(const HilogData *data) return buffer; } -LogPersister::LogPersister(string name, string path, uint16_t compressType, +LogPersister::LogPersister(uint32_t id, string path, uint16_t compressType, uint16_t compressAlg, int sleepTime, LogPersisterRotator *rotator, HilogBuffer *_buffer) - : name(name), path(path), compressType(compressType), compressAlg(compressAlg), + : id(id), path(path), compressType(compressType), compressAlg(compressAlg), sleepTime(sleepTime), rotator(rotator) { + toExit = false; hasExited = false; hilogBuffer = _buffer; LogCompress = nullptr; @@ -93,22 +94,31 @@ int LogPersister::Init() if (realPath == nullptr) { return RET_FAIL; } - path = std::string(cPath); if (path.rfind(g_logPersisterDir, 0) != 0) { return RET_FAIL; } - int nPos = path.find_last_of('/'); if (nPos == RET_FAIL) { return RET_FAIL; } - mmapPath = path.substr(0, nPos) + "/." + name; + mmapPath = path.substr(0, nPos) + "/." + to_string(id); if (access(path.substr(0, nPos).c_str(), F_OK) != 0) { if (errno == ENOENT) { MkDirPath(path.substr(0, nPos).c_str()); } } + bool hit = false; + const lock_guard lock(g_listMutex); + for (auto it = logPersisters.begin(); it != logPersisters.end(); ++it) + if ((*it)->getPath() == path || (*it)->Identify(id)) { + std::cout << path << std::endl; + hit = true; + break; + } + if (hit) { + return RET_FAIL; + } fd = open(mmapPath.c_str(), O_RDWR | O_CREAT | O_EXCL, 0); bool restore = false; if (fd <= 0) { @@ -124,14 +134,12 @@ int LogPersister::Init() lseek(fd, MAX_PERSISTER_BUFFER_SIZE - 1, SEEK_SET); write(fd, "", 1); } - if (fd < 0) { #ifdef DEBUG cout << "open log file(" << mmapPath << ") failed: " << strerror(errno) << endl; #endif return RET_FAIL; } - fdinfo = fopen((mmapPath + ".info").c_str(), "r+"); if (fdinfo == nullptr) { fdinfo = fopen((mmapPath + ".info").c_str(), "w+"); @@ -166,13 +174,13 @@ int LogPersister::Init() } else { SetBufferOffset(0); } + logPersisters.push_back(std::static_pointer_cast(shared_from_this())); return 0; } void LogPersister::NotifyForNewData() { - condVariable.notify_one(); - SetWaitForNewData(false); + condVariable.notify_one(); isNotified = true; } @@ -247,26 +255,12 @@ int LogPersister::WriteData(HilogData *data) return writeUnCompressedBuffer(data) ? 0 : -1; } -int LogPersister::Start() +void LogPersister::Start() { - bool hit = false; - std::lock_guard guard(g_listMutex); - - for (auto it = logPersisters.begin(); it != logPersisters.end(); ++it) { - if ((*it)->Identify(name, path)) { - hit = true; - break; - } - } - - if (!hit) { - logPersisters.push_back(static_pointer_cast(shared_from_this())); - std::cout << "PERSISTER CREATION SUCCESS" << std::endl; - auto newThread = - thread(&LogPersister::ThreadFunc, static_pointer_cast(shared_from_this())); - newThread.detach(); - } - return hit ? -1 : 0; + auto newThread = + thread(&LogPersister::ThreadFunc, static_pointer_cast(shared_from_this())); + newThread.detach(); + return; } inline void LogPersister::WriteFile() @@ -283,14 +277,14 @@ int LogPersister::ThreadFunc() std::thread::id tid = std::this_thread::get_id(); cout << __func__ << " " << tid << endl; while (true) { - if (hasExited) { + if (toExit) { break; } if (!hilogBuffer->Query(shared_from_this())) { unique_lock lk(cvMutex); if (condVariable.wait_for(lk, sleepTime * 1s) == cv_status::timeout) { - if (hasExited) { + if (toExit) { break; } WriteFile(); @@ -299,6 +293,10 @@ int LogPersister::ThreadFunc() cout << "running! " << compressAlg << endl; } WriteFile(); + { + std::lock_guard guard(mutexForhasExited); + hasExited = true; + } cvhasExited.notify_all(); return 0; } @@ -322,9 +320,7 @@ int LogPersister::Query(uint16_t logType, list &results) void LogPersister::FillInfo(LogPersistQueryResult *response) { - if (strcpy_s(response->jobId, JOB_ID_MAX_LEN, name.c_str())) { - return; - } + response->jobId = id; if (strcpy_s(response->filePath, FILE_PATH_MAX_LEN, path.c_str())) { return; } @@ -334,13 +330,13 @@ void LogPersister::FillInfo(LogPersistQueryResult *response) return; } -int LogPersister::Kill(const string &name) +int LogPersister::Kill(const uint32_t id) { bool found = false; std::lock_guard guard(g_listMutex); for (auto it = logPersisters.begin(); it != logPersisters.end(); ) { - cout << "find a persister" << endl; - if ((*it)->Identify(name)) { + if ((*it)->Identify(id)) { + cout << "find a persister" << endl; (*it)->Exit(); it = logPersisters.erase(it); found = true; @@ -351,16 +347,21 @@ int LogPersister::Kill(const string &name) return found ? 0 : -1; } -void LogPersister::Exit() +bool LogPersister::isExited() { - hasExited = true; - condVariable.notify_one(); + return hasExited; +} +void LogPersister::Exit() +{ + toExit = true; + condVariable.notify_all(); unique_lock lk(mutexForhasExited); - cvhasExited.wait(lk); + if (!isExited()) { + cvhasExited.wait(lk); + } delete rotator; this->rotator = nullptr; - munmap(buffer, MAX_PERSISTER_BUFFER_SIZE); cout << "removed mmap file" << endl; remove(mmapPath.c_str()); @@ -368,18 +369,14 @@ void LogPersister::Exit() fclose(fdinfo); return; } -bool LogPersister::Identify(const string &name, const string &path) +bool LogPersister::Identify(uint32_t id) { - if (path.empty()) { - return this->name.compare(name) == 0; - } else { - return this->name.compare(name) == 0 && this->path.compare(path) == 0; - } + return this->id == id; } -std::string LogPersister::GetName() +string LogPersister::getPath() { - return name; + return path; } uint8_t LogPersister::getType() const diff --git a/services/hilogd/log_querier.cpp b/services/hilogd/log_querier.cpp index fd7ecefd90ed46dde37a2a1ab64b46d54ef0f004..e08ed10171e9888430dae2f120426f7eadeea3fa 100644 --- a/services/hilogd/log_querier.cpp +++ b/services/hilogd/log_querier.cpp @@ -41,7 +41,7 @@ namespace OHOS { namespace HiviewDFX { using namespace std; -constexpr int MAX_DATA_LEN = 4096; +constexpr int MAX_DATA_LEN = 2048; constexpr int DEFAULT_LOG_LEVEL = 1< logReader, HilogBuffer* buffer void HandlePersistStartRequest(char* reqMsg, std::shared_ptr logReader, HilogBuffer* buffer) { char msgToSend[MAX_DATA_LEN]; + const uint16_t sendMsgLen = sizeof(LogPersistStartResult); + LogPersisterRotator *rotator = nullptr; LogPersistStartRequest* pLogPersistStartReq = reinterpret_cast(reqMsg); LogPersistStartMsg* pLogPersistStartMsg @@ -118,53 +120,28 @@ void HandlePersistStartRequest(char* reqMsg, std::shared_ptr logReade = reinterpret_cast(msgToSend); LogPersistStartResult* pLogPersistStartRst = reinterpret_cast(&pLogPersistStartRsp->logPersistStartRst); - - uint32_t recvMsgLen = 0; - uint32_t msgNum = 0; - uint16_t sendMsgLen = 0; - int32_t rst = 0; - LogPersisterRotator *rotator = nullptr; - - const auto findIter = std::find_if(buffer->logReaderList.begin(), buffer->logReaderList.end(), - [pLogPersistStartMsg](const std::weak_ptr& ptr0) { - return ptr0.lock()->getType() == TYPE_PERSISTER && - !(static_pointer_cast(ptr0.lock())->GetName().compare(std::string(pLogPersistStartMsg->jobId))); - }); - if (findIter != buffer->logReaderList.end()) { - std::cout << "Persister exists!" << std::endl; - rst = 0; - } else { - rotator = MakeRotator(*pLogPersistStartMsg); - std::shared_ptr persister = make_shared( + if (pLogPersistStartRst == nullptr) { + return; + } + rotator = MakeRotator(*pLogPersistStartMsg); + std::shared_ptr persister = make_shared( pLogPersistStartMsg->jobId, pLogPersistStartMsg->filePath, pLogPersistStartMsg->compressType, pLogPersistStartMsg->compressAlg, SLEEP_TIME, rotator, buffer); - rst = persister->Init(); - if (rst == RET_FAIL) { - persister.reset(); - return; - } - persister->queryCondition.types = pLogPersistStartMsg->logType; - persister->queryCondition.levels = DEFAULT_LOG_LEVEL; - rst = persister->Start(); - if (rst == 0) { - buffer->AddLogReader(weak_ptr(persister)); - } - } - if (pLogPersistStartRst) { - if (strcpy_s(pLogPersistStartRst->jobId, JOB_ID_MAX_LEN, pLogPersistStartMsg->jobId)) { - // not break; - } - pLogPersistStartRst->result = (rst < 0) ? RET_FAIL : RET_SUCCESS; - pLogPersistStartRst++; + + pLogPersistStartRst->jobId = pLogPersistStartMsg->jobId; + pLogPersistStartRst->result = persister->Init(); + persister->queryCondition.types = pLogPersistStartMsg->logType; + persister->queryCondition.levels = DEFAULT_LOG_LEVEL; + if (pLogPersistStartRst->result == RET_FAIL) { + persister.reset(); + } else { + persister->Start(); + buffer->AddLogReader(weak_ptr(persister)); } - pLogPersistStartMsg++; - recvMsgLen += sizeof(LogPersistStartMsg); - msgNum++; - sendMsgLen = msgNum * sizeof(LogPersistStartResult); SetMsgHead(&pLogPersistStartRsp->msgHeader, MC_RSP_LOG_PERSIST_START, sendMsgLen); logReader->hilogtoolConnectSocket->Write(msgToSend, sendMsgLen + sizeof(MessageHeader)); } @@ -193,9 +170,7 @@ void HandlePersistDeleteRequest(char* reqMsg, std::shared_ptr logRead while (pLogPersistStopMsg && recvMsgLen < msgLen) { rst = LogPersister::Kill(pLogPersistStopMsg->jobId); if (pLogPersistStopRst) { - if (strcpy_s(pLogPersistStopRst->jobId, JOB_ID_MAX_LEN, pLogPersistStopMsg->jobId)) { - return; - } + pLogPersistStopRst->jobId = pLogPersistStopMsg->jobId; pLogPersistStopRst->result = (rst < 0) ? RET_FAIL : RET_SUCCESS; pLogPersistStopRst++; } @@ -234,13 +209,11 @@ void HandlePersistQueryRequest(char* reqMsg, std::shared_ptr logReade while (pLogPersistQueryMsg && recvMsgLen < msgLen) { list resultList; cout << pLogPersistQueryMsg->logType << endl; - rst = LogPersister::Query(0b01 << pLogPersistQueryMsg->logType, resultList); + rst = LogPersister::Query(pLogPersistQueryMsg->logType, resultList); for (it = resultList.begin(); it != resultList.end(); ++it) { if (pLogPersistQueryRst) { pLogPersistQueryRst->result = (rst < 0) ? RET_FAIL : RET_SUCCESS; - if (strcpy_s(pLogPersistQueryRst->jobId, JOB_ID_MAX_LEN, (*it).jobId)) { - return; - } + pLogPersistQueryRst->jobId = (*it).jobId; pLogPersistQueryRst->logType = (*it).logType; pLogPersistQueryRst->compressType = (*it).compressType; pLogPersistQueryRst->compressAlg = (*it).compressAlg; @@ -250,7 +223,11 @@ void HandlePersistQueryRequest(char* reqMsg, std::shared_ptr logReade pLogPersistQueryRst->fileSize = (*it).fileSize; pLogPersistQueryRst->fileNum = (*it).fileNum; pLogPersistQueryRst++; - msgNum++; + msgNum++; + if (msgNum * sizeof(LogPersistQueryResult) + sizeof(MessageHeader) > MAX_DATA_LEN) { + msgNum--; + break; + } } } pLogPersistQueryMsg++; @@ -434,10 +411,7 @@ void LogQuerier::LogQuerierThreadFunc(std::shared_ptr logReader) case NEXT_REQUEST: nRstMsg = (NextRequest*) g_tempBuffer; if (nRstMsg->sendId == SENDIDA) { - logReader->SetWaitForNewData(false); HandleNextRequest(logReader, hilogBuffer); - } else if (nRstMsg->sendId == SENDIDS) { - logReader->SetWaitForNewData(true); } break; case MC_REQ_LOG_PERSIST_START: @@ -528,7 +502,6 @@ void LogQuerier::NotifyForNewData() SetMsgHead(&(rsp.header), NEXT_RESPONSE, sizeof(rsp)); int ret = WriteData(rsp, nullptr); if (ret > 0) { - SetWaitForNewData(false); isNotified = true; } } diff --git a/services/hilogd/log_reader.cpp b/services/hilogd/log_reader.cpp index 7807d2983f162d31bc508ca8959ba53a3320f891..0bb7b2fa5b3c0dc06c2fbed4ed301aa8cf5e4649 100644 --- a/services/hilogd/log_reader.cpp +++ b/services/hilogd/log_reader.cpp @@ -34,12 +34,12 @@ LogReader::LogReader() queryCondition.types = 0; queryCondition.timeBegin = 0; queryCondition.timeEnd = 0; - waitForNewData = false; isNotified = false; } LogReader::~LogReader() { + hilogBuffer->logReaderListMutex.lock(); const auto findIter = std::find_if(hilogBuffer->logReaderList.begin(), hilogBuffer->logReaderList.end(), [this](const std::weak_ptr& ptr0) { return ptr0.lock() == weak_from_this().lock(); @@ -47,17 +47,7 @@ LogReader::~LogReader() if (findIter != hilogBuffer->logReaderList.end()) { hilogBuffer->logReaderList.erase(findIter); } -} - -bool LogReader::SetWaitForNewData(bool flag) -{ - waitForNewData = flag; - return true; -} - -bool LogReader::GetWaitForNewData() const -{ - return waitForNewData; + hilogBuffer->logReaderListMutex.unlock(); } void LogReader::NotifyReload() diff --git a/services/hilogd/main.cpp b/services/hilogd/main.cpp index 85e159c07c22f296c8d83f8bf01a908c2d658546..12632927c5ba2e5777a0d3eb25f8ebe41d41dd14 100644 --- a/services/hilogd/main.cpp +++ b/services/hilogd/main.cpp @@ -64,7 +64,6 @@ int HilogdEntry(int argc, char* argv[]) std::signal(SIGINT, SigHandler); InitDomainFlowCtrl(); - InitProcessFlowCtrl(); // Start log_collector LogCollector logCollector(&hilogBuffer); diff --git a/services/hilogtool/log_controller.cpp b/services/hilogtool/log_controller.cpp index 113ff993b6735bcd3f13a37088235dd017b40f83..d8284f21275c04503b03f7441c5edc7da8a2ac10 100644 --- a/services/hilogtool/log_controller.cpp +++ b/services/hilogtool/log_controller.cpp @@ -17,10 +17,12 @@ #include #include -#include +#include #include #include +#include #include + #include "hilog/log.h" #include "hilog_common.h" #include "hilogtool_msg.h" @@ -33,6 +35,9 @@ namespace HiviewDFX { using namespace std; const int MSG_MAX_LEN = 2048; +const int LOG_PERSIST_FILE_SIZE = 4 * ONE_MB; +const int LOG_PERSIST_FILE_NUM = 10; + void SetMsgHead(MessageHeader* msgHeader, const uint8_t msgCmd, const uint16_t msgLen) { if (!msgHeader) { @@ -78,7 +83,7 @@ uint16_t GetLogType(const string& logTypeStr) } else if (logTypeStr == "app") { logType = LOG_APP; } else { - logType = LOG_TYPE_MAX; + return 0xffff; } return logType; } @@ -102,7 +107,7 @@ uint64_t GetBuffSize(const string& buffSizeStr) } return buffSize; } -int16_t GetLogLevel(const string &logLevelStr) +uint16_t GetLogLevel(const string& logLevelStr) { if (logLevelStr == "debug" || logLevelStr == "DEBUG") { return LOG_DEBUG; @@ -112,10 +117,10 @@ int16_t GetLogLevel(const string &logLevelStr) return LOG_WARN; } else if (logLevelStr == "error" || logLevelStr == "ERROR") { return LOG_ERROR; - } else if (logLevelStr == "fatal" || logLevelStr == "DEBUG") { + } else if (logLevelStr == "fatal" || logLevelStr == "FATAL") { return LOG_FATAL; } else { - return RET_FAIL; + return 0xffff; } } @@ -147,7 +152,11 @@ void LogQueryRequestOp(SeqPacketSocketClient& controller, const HilogArgs* conte logQueryRequest.levels = context->levels; logQueryRequest.types = context->types; if (context->domainArgs != "") { - logQueryRequest.domain = std::stoi(context->domainArgs, 0, DOMAIN_NUMBER_BASE); + std::istringstream(context->domainArgs) >> std::hex >> logQueryRequest.domain; + if (logQueryRequest.domain == 0) { + std::cout << "Invalid parameter" << std::endl; + return; + } } logQueryRequest.timeBegin = context->beginTime; logQueryRequest.timeEnd = context->endTime; @@ -179,21 +188,19 @@ void LogQueryResponseOp(SeqPacketSocketClient& controller, char* recvBuffer, uin if (context->noBlockMode) { if (context->tailLines) { while (context->tailLines-- && !tailBuffer.empty()) { - cout << tailBuffer.back() <> domain; + if (domain == 0) { + std::cout << "Invalid parameter" << std::endl; + return RET_FAIL; + } } switch (msgCmd) { case MC_REQ_STATISTIC_INFO_QUERY: @@ -330,18 +341,13 @@ int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersi uint32_t jobIdNum; uint32_t iter; int ret = 0; + uint32_t fileSizeDefault = LOG_PERSIST_FILE_SIZE; + uint32_t fileNumDefault = LOG_PERSIST_FILE_NUM; string logType = SetDefaultLogType(logPersistParam->logTypeStr); Split(logType, " ", vecLogType); Split(logPersistParam->jobIdStr, " ", vecJobId); logTypeNum = vecLogType.size(); jobIdNum = vecJobId.size(); - if (msgCmd == MC_REQ_LOG_PERSIST_START && - (logPersistParam->compressTypeStr == "" || logPersistParam->fileSizeStr == "" || - logPersistParam->filePathStr == "" || logPersistParam->fileNumStr == "" || - logPersistParam->compressAlgStr == "" || logPersistParam->jobIdStr == "" || - jobIdNum != 1)) { // all param need, start only one job each time,logType support union - return RET_FAIL; - } if (msgCmd == MC_REQ_LOG_PERSIST_STOP && logPersistParam->jobIdStr == "") { // support stop several jobs each time return RET_FAIL; } @@ -360,17 +366,23 @@ int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersi } pLogPersistStartMsg->logType = (0b01 << tmpType) | pLogPersistStartMsg->logType; } - pLogPersistStartMsg->compressType = stoi(logPersistParam->compressTypeStr); - pLogPersistStartMsg->compressAlg = - (pLogPersistStartMsg->compressType != 1) ? 0 : stoi(logPersistParam->compressAlgStr); - pLogPersistStartMsg->fileSize = stoi(logPersistParam->fileSizeStr); - pLogPersistStartMsg->fileNum = stoi(logPersistParam->fileNumStr); - if (logPersistParam->filePathStr.size() > FILE_PATH_MAX_LEN || - logPersistParam->jobIdStr.size() > JOB_ID_MAX_LEN) { + pLogPersistStartMsg->jobId = (logPersistParam->jobIdStr == "") ? time(nullptr) + : stoi(logPersistParam->jobIdStr); + pLogPersistStartMsg->compressType = (logPersistParam->compressTypeStr == "") ? STREAM : stoi(logPersistParam + ->compressTypeStr); + pLogPersistStartMsg->compressAlg = (logPersistParam->compressAlgStr == "") ? COMPRESS_TYPE_ZLIB : stoi( + logPersistParam->compressAlgStr); + pLogPersistStartMsg->fileSize = (logPersistParam->fileSizeStr == "") ? fileSizeDefault : stoi( + logPersistParam->fileSizeStr); + pLogPersistStartMsg->fileNum = (logPersistParam->fileNumStr == "") ? fileNumDefault + : stoi(logPersistParam->fileNumStr); + if (logPersistParam->filePathStr == "") { + logPersistParam->filePathStr = "/data/misc/logd/log_" + to_string(time(nullptr)); + } + if (logPersistParam->filePathStr.size() > FILE_PATH_MAX_LEN) { return RET_FAIL; } ret += strcpy_s(pLogPersistStartMsg->filePath, FILE_PATH_MAX_LEN, logPersistParam->filePathStr.c_str()); - ret += strcpy_s(pLogPersistStartMsg->jobId, JOB_ID_MAX_LEN, logPersistParam->jobIdStr.c_str()); SetMsgHead(&pLogPersistStartReq->msgHeader, msgCmd, sizeof(LogPersistStartRequest)); controller.WriteAll(msgToSend, sizeof(LogPersistStartRequest)); break; @@ -385,11 +397,10 @@ int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersi return RET_FAIL; } for (iter = 0; iter < jobIdNum; iter++) { - ret += strcpy_s(pLogPersistStopMsg->jobId, JOB_ID_MAX_LEN, vecJobId[iter].c_str()); + pLogPersistStopMsg->jobId = stoi(vecJobId[iter]); pLogPersistStopMsg++; } SetMsgHead(&pLogPersistStopReq->msgHeader, msgCmd, sizeof(LogPersistStopMsg) * jobIdNum); - controller.WriteAll(msgToSend, sizeof(LogPersistStopMsg) * jobIdNum + sizeof(MessageHeader)); break; } @@ -399,19 +410,16 @@ int32_t LogPersistOp(SeqPacketSocketClient& controller, uint8_t msgCmd, LogPersi reinterpret_cast(msgToSend); LogPersistQueryMsg* pLogPersistQueryMsg = reinterpret_cast(&pLogPersistQueryReq->logPersistQueryMsg); - if (logTypeNum * sizeof(LogPersistQueryMsg) + sizeof(MessageHeader) > MSG_MAX_LEN) { - return RET_FAIL; - } + for (iter = 0; iter < logTypeNum; iter++) { uint16_t tmpType = GetLogType(vecLogType[iter]); if (tmpType == 0xffff) { return RET_FAIL; } - pLogPersistQueryMsg->logType = tmpType; - pLogPersistQueryMsg++; + pLogPersistQueryMsg->logType = (0b01 << tmpType) | pLogPersistQueryMsg->logType; } - SetMsgHead(&pLogPersistQueryReq->msgHeader, msgCmd, sizeof(LogPersistQueryMsg) * logTypeNum); - controller.WriteAll(msgToSend, sizeof(LogPersistQueryMsg) * logTypeNum + sizeof(MessageHeader)); + SetMsgHead(&pLogPersistQueryReq->msgHeader, msgCmd, sizeof(LogPersistQueryMsg)); + controller.WriteAll(msgToSend, sizeof(LogPersistQueryRequest)); break; } @@ -439,36 +447,39 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType tagNum = vecTag.size(); switch (operationType) { case OT_PRIVATE_SWITCH: + key = GetPropertyName(PROP_PRIVATE); if (propertyParm->privateSwitchStr == "on") { - PropertySet("hilog.private.on", "true"); + PropertySet(key.c_str(), "true"); cout << "hilog private formatter is enabled" << endl; } if (propertyParm->privateSwitchStr == "off") { - PropertySet("hilog.private.on", "false"); + PropertySet(key.c_str(), "false"); cout << "hilog private formatter is disabled" << endl; } break; case OT_LOG_LEVEL: if ((propertyParm->tagStr != "" && propertyParm->domainStr != "") || GetLogLevel(propertyParm->logLevelStr) - == RET_FAIL) { + == 0xffff) { return RET_FAIL; } else if (propertyParm->domainStr != "") { // by domain + std::string keyPre = GetPropertyName(PROP_DOMAIN_LOG_LEVEL); for (iter = 0; iter < domainNum; iter++) { - key = "hilog.loggable.domain." + vecDomain[iter]; + key = keyPre + vecDomain[iter]; value = to_string(GetLogLevel(propertyParm->logLevelStr)); PropertySet(key.c_str(), value.c_str()); cout << "domain " << vecDomain[iter] << " level is set to " << propertyParm->logLevelStr << endl; } } else if (propertyParm->tagStr != "") { // by tag + std::string keyPre = GetPropertyName(PROP_TAG_LOG_LEVEL); for (iter = 0; iter < tagNum; iter++) { - key = "hilog.loggable.tag." + vecTag[iter]; - value = to_string(GetLogLevel(propertyParm->logLevelStr)); - PropertySet(key.c_str(), value.c_str()); + key = keyPre + vecTag[iter]; + value = to_string(GetLogLevel(propertyParm->logLevelStr)); + PropertySet(key.c_str(), value.c_str()); cout << "tag " << vecTag[iter] << " level is set to " << propertyParm->logLevelStr << endl; } } else { - key = "hilog.loggable.global"; + key = GetPropertyName(PROP_GLOBAL_LOG_LEVEL); value = to_string(GetLogLevel(propertyParm->logLevelStr)); PropertySet(key.c_str(), value.c_str()); cout << "global log level is set to " << propertyParm->logLevelStr << endl; @@ -477,19 +488,23 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType case OT_FLOW_SWITCH: if (propertyParm->flowSwitchStr == "pidon") { - PropertySet("hilog.flowctrl.pid", "on"); + key = GetPropertyName(PROP_PROCESS_FLOWCTRL); + PropertySet(key.c_str(), "true"); cout << "flow control by process is enabled" << endl; } if (propertyParm->flowSwitchStr == "pidoff") { - PropertySet("hilog.flowctrl.pid", "off"); + key = GetPropertyName(PROP_PROCESS_FLOWCTRL); + PropertySet(key.c_str(), "false"); cout << "flow control by process is disabled" << endl; } if (propertyParm->flowSwitchStr == "domainon") { - PropertySet("hilog.flowctrl.domain", "on"); + key = GetPropertyName(PROP_DOMAIN_FLOWCTRL); + PropertySet(key.c_str(), "true"); cout << "flow control by domain is enabled" << endl; } if (propertyParm->flowSwitchStr == "domainoff") { - PropertySet("hilog.flowctrl.domain", "off"); + key = GetPropertyName(PROP_DOMAIN_FLOWCTRL); + PropertySet(key.c_str(), "false"); cout << "flow control by domain is disabled" << endl; } break; diff --git a/services/hilogtool/log_display.cpp b/services/hilogtool/log_display.cpp index 7502c311b46b9af1bae7aa98c047f24641a0dd48..540c0d4730c6633b19e9b7329431f4f43f0731f4 100644 --- a/services/hilogtool/log_display.cpp +++ b/services/hilogtool/log_display.cpp @@ -271,11 +271,11 @@ int32_t ControlCmdResult(const char* message) (LogPersistStartResult*)&pLogPersistStartRsp->logPersistStartRst; while (pLogPersistStartRst && resultLen < msgLen) { if (pLogPersistStartRst->result == RET_FAIL) { - outputStr += pLogPersistStartRst->jobId; + outputStr += to_string(pLogPersistStartRst->jobId); outputStr += " log file task start fail"; outputStr += "\n"; } else { - outputStr += pLogPersistStartRst->jobId; + outputStr += to_string(pLogPersistStartRst->jobId); outputStr += " log file task start success"; outputStr += "\n"; } @@ -292,11 +292,11 @@ int32_t ControlCmdResult(const char* message) LogPersistStopResult* pLogPersistStopRst = (LogPersistStopResult*)&pLogPersistStopRsp->logPersistStopRst; while (pLogPersistStopRst && resultLen < msgLen) { if (pLogPersistStopRst->result == RET_FAIL) { - outputStr += pLogPersistStopRst->jobId; + outputStr += to_string(pLogPersistStopRst->jobId); outputStr += " log file task stop fail"; outputStr += "\n"; } else { - outputStr += pLogPersistStopRst->jobId; + outputStr += to_string(pLogPersistStopRst->jobId); outputStr += " log file task stop success"; outputStr += "\n"; } @@ -318,7 +318,7 @@ int32_t ControlCmdResult(const char* message) outputStr = " log file task query fail"; outputStr += "\n"; } else { - outputStr += pLogPersistQueryRst->jobId; + outputStr += to_string(pLogPersistQueryRst->jobId); outputStr += " "; outputStr += GetOrigType(pLogPersistQueryRst->logType); outputStr += " "; @@ -451,8 +451,7 @@ void HilogShowLog(HilogShowFormat showFormat, HilogDataMessage* data, HilogArgs* tailBuffer.emplace_back(buffer); return; } - - cout << buffer < #include #include +#include #include #include +#include #include #include + #include "hilog/log.h" #include "hilog_common.h" #include "hilogtool_msg.h" @@ -82,7 +85,7 @@ static void Helper() " -n , --number\n" " set max log file numbers.\n" " -j , --jobid\n" - " stop the log file writing task of .\n" + " start/stop the log file writing task of .\n" " -w ,--write=\n" " query log file writing task query.\n" " start start a log file writing task, see -F -l -n -c for to set more configs,\n" @@ -91,7 +94,9 @@ static void Helper() " multiple conditions query\n" " -v , --format= options:\n" " time display local time.\n" - " color display colorful logs by log level.\n" + " color display colorful logs by log level.i.e. \x1B[38;5;231mVERBOSE\n" + " \x1B[38;5;75mDEBUG \x1B[38;5;40mINFO \x1B[38;5;166mWARN" + " \x1B[38;5;196mERROR \x1B[38;5;226mFATAL\x1B[0m\n" " epoch display the time from 1970/1/1.\n" " monotonic display the cpu time from bootup.\n" " usec display time by usec.\n" @@ -101,59 +106,19 @@ static void Helper() ); } -static int Str2Time(const std::string &dateStr, time_t &timeData) +static std::time_t Str2Time(const std::string& str, bool isDst = false, + const std::string& format = "%Y-%m-%d_%H:%M:%S") { - timeData = 0; - if (dateStr == "") { + if (str == "") { return 0; + } else { + std::tm t = {0}; + t.tm_isdst = isDst ? 1 : 0; + std::istringstream ss(str); + ss >> std::get_time(&t, format.c_str()); + return mktime(&t); } - - const char *pData = strdup(dateStr.c_str()); - if (pData == nullptr) { - return -1; - } - - const char *pos = strstr(pData, "-"); - if (pos == nullptr) { - free((void *)pData); - return -1; - } - int year = atoi(pData); - int month = atoi(pos + 1); - pos = strstr(pos + 1, "-"); - if (pos == nullptr) { - free((void *)pData); - return -1; - } - int day = atoi(pos + 1); - int hour = 0; - int min = 0; - int sec = 0; - pos = strstr(pos + 1, "_"); - if (pos != nullptr) { - hour = atoi(pos + 1); - pos = strstr(pos + 1, ":"); - if (pos != nullptr) { - min = atoi(pos + 1); - pos = strstr(pos + 1, ":"); - if (pos != nullptr) { - sec = atoi(pos + 1); - } - } - } - struct tm originData = { 0 }; - bzero(static_cast(&originData), sizeof(originData)); - originData.tm_sec = sec; - originData.tm_min = min; - originData.tm_hour = hour; - originData.tm_mday = day; - originData.tm_mon = month - 1; - originData.tm_year = year - 1900; - timeData = mktime(&originData); - free((void *)pData); - return 0; } - static int GetTypes(HilogArgs context, string typesArgs) { uint16_t types = context.types; @@ -262,8 +227,14 @@ int HilogEntry(int argc, char* argv[]) break; case 'z': context.tailLines = atoi(optarg); + context.noBlockMode = 1; break; case 't': + context.logTypeArgs = optarg; + if (context.logTypeArgs.find("all") != context.logTypeArgs.npos || + context.logTypeArgs.find(" ") != context.logTypeArgs.npos) { + break; + } indexType = optind - 1; while (indexType < argc) { string types(argv[indexType]); @@ -306,12 +277,12 @@ int HilogEntry(int argc, char* argv[]) idex++; } } - if (vecSrc.size() != MULARGS) { + if (vecSrc.size() > MULARGS) { std::cout<<"Invalid parameter"<