From 16b6cef7d7f88c0fd15a1a883be52d3fcdde570b Mon Sep 17 00:00:00 2001 From: yaomanhai Date: Sun, 30 Jan 2022 08:15:52 +0000 Subject: [PATCH] hilog tool code refactor Signed-off-by: yaomanhai --- adapter/properties.cpp | 573 ++++++++++--------------- adapter/properties.h | 34 +- services/hilogtool/include/log_utils.h | 31 ++ services/hilogtool/log_controller.cpp | 173 ++------ services/hilogtool/log_display.cpp | 188 +------- services/hilogtool/log_utils.cpp | 306 +++++++++++++ 6 files changed, 616 insertions(+), 689 deletions(-) create mode 100644 services/hilogtool/include/log_utils.h create mode 100644 services/hilogtool/log_utils.cpp diff --git a/adapter/properties.cpp b/adapter/properties.cpp index 048647f..04a2306 100644 --- a/adapter/properties.cpp +++ b/adapter/properties.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,422 +12,295 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "properties.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include +#include #include -#include -#include +#include "log_utils.h" +#include "hilog_common.h" +#include "hilogtool_msg.h" +namespace OHOS { +namespace HiviewDFX { using namespace std; -using ReadLock = shared_lock; -using InsertLock = unique_lock; - -static pthread_mutex_t g_globalLevelLock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t g_tagLevelLock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t g_domainLevelLock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t g_debugLock = PTHREAD_MUTEX_INITIALIZER; -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_kmsgLock = PTHREAD_MUTEX_INITIALIZER; - -static int LockByProp(uint32_t propType); -static void UnlockByProp(uint32_t propType); - -class PropertyTypeLocker { -public: - explicit PropertyTypeLocker(uint32_t propType) - : m_propType(propType) - , m_isLocked(false) - { - m_isLocked = !LockByProp(m_propType); - } - - ~PropertyTypeLocker() - { - if (m_isLocked) { - UnlockByProp(m_propType); - } - } - - bool isLocked() const - { - return m_isLocked; - } -private: - uint32_t m_propType; - bool m_isLocked; -}; - -using RawPropertyData = std::array; -template -class CacheData { -public: - using DataConverter = std::function; +template +static V FindValueByKey(std::unordered_map map, K key, V& def) +{ + auto it = map.find(key); + return it == map.end() ? def : it->second; +} - CacheData(DataConverter converter, const T& defaultValue, uint32_t propType, const std::string& suffix = "") - : m_value(defaultValue) - , m_defaultValue(defaultValue) - , m_propType(propType) - , m_converter(converter) - { - m_key = GetPropertyName(m_propType) + suffix; - } +static bool StringCmp(std::string& s1, std::string& s2) +{ + return s1 == s2; +} - T getValue() - { - if (m_handle == -1) { - auto handle = FindParameter(m_key.c_str()); - if (handle == -1) { - return m_defaultValue; - } - m_handle = handle; - } - auto currentCommit = GetParameterCommitId(m_handle); - PropertyTypeLocker locker(m_propType); - if (locker.isLocked()) { - if (currentCommit != m_commit) { - updateValue(); - m_commit = currentCommit; - } - return m_value; - } else { - return getDirectValue(); - } - } -private: - bool getRawValue(char *value, unsigned int len) - { - auto res = GetParameterValue(m_handle, value, len); - if (res < 0) { - std::cerr << "CacheData -> GetParameterValue -> Can't get value for key: " << m_key; - std::cerr << " handle: " << m_handle << " Result: " << res << "\n"; - return false; - } - return true; - } +template +static K FindKeyByValue(std::unordered_map map, V& value, K def, std::function cmp) +{ + auto it = map.begin(); - T getDirectValue() - { - RawPropertyData tempData; - if (!getRawValue(tempData.data(), tempData.size())) { - return m_defaultValue; + for(auto it = map.begin(); it == map.end(); it++) { + if (cmp(it->second, value)) { + return it->first; } - return m_converter(tempData, m_defaultValue); } + return def; +} - void updateValue() - { - if (!getRawValue(m_rawData.data(), m_rawData.size())) { - m_value = m_defaultValue; - return; - } - m_value = m_converter(m_rawData, m_defaultValue); - } - RawPropertyData m_rawData = {0}; - unsigned int m_handle = -1; - unsigned int m_commit = -1; - T m_value; - const T m_defaultValue; - const uint32_t m_propType; - std::string m_key; - DataConverter m_converter; +static const unordered_map g_ErrorMsg +{ + {RET_FAIL, "Unexpected error"}, + {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F"}, + {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg"}, + {ERR_QUERY_TYPE_INVALID, "Query condition on both types and excluded types is undefined or\ + queryTypes can not contain app/core/init and kmsg at the same time"}, + {ERR_QUERY_LEVEL_INVALID, "Query condition on both levels and excluded levels is undefined"}, + {ERR_QUERY_DOMAIN_INVALID, "Invalid domain format, a hexadecimal number is needed"}, + {ERR_QUERY_TAG_INVALID, "Query condition on both tags and excluded tags is undefined"}, + {ERR_QUERY_PID_INVALID, "Query condition on both pid and excluded pid is undefined"}, + {ERR_BUFF_SIZE_EXP, "Buffer resize exception"}, + {ERR_LOG_PERSIST_FILE_SIZE_INVALID, "Invalid log persist file size, file size should be not less than " + + to_string(MAX_PERSISTER_BUFFER_SIZE)}, + {ERR_LOG_PERSIST_FILE_NAME_INVALID, "Invalid log persist file name, file name should not contain [\\/:*?\"<>|]"}, + {ERR_LOG_PERSIST_COMPRESS_BUFFER_EXP, "Invalid Log persist compression buffer"}, + {ERR_LOG_PERSIST_FILE_PATH_INVALID, "Invalid persister file path or persister directory does not exist"}, + {ERR_LOG_PERSIST_COMPRESS_INIT_FAIL, "Log persist compression initialization failed"}, + {ERR_LOG_PERSIST_FILE_OPEN_FAIL, "Log persist open file failed"}, + {ERR_LOG_PERSIST_MMAP_FAIL, "Log persist mmap failed"}, + {ERR_LOG_PERSIST_JOBID_FAIL, "Log persist jobid not exist"}, + {ERR_LOG_PERSIST_TASK_FAIL, "Log persist task is existed"}, + {ERR_DOMAIN_INVALID, "Invalid domain, domain should not be more than 0 and less than " + + to_string(DOMAIN_MAX_SCOPE)}, + {ERR_MEM_ALLOC_FAIL, "Alloc memory failed"}, + {ERR_MSG_LEN_INVALID, "Invalid message length, message length should be not more than " + + to_string(MSG_MAX_LEN)}, + {ERR_PRIVATE_SWITCH_VALUE_INVALID, "Invalid private switch value, valid:on/off"}, + {ERR_FLOWCTRL_SWITCH_VALUE_INVALID, "Invalid flowcontrl switch value, valid:pidon/pidoff/domainon/domainoff"}, + {ERR_LOG_PERSIST_JOBID_INVALID, "Invalid jobid, jobid should be more than 0"}, + {ERR_LOG_CONTENT_NULL, "Log content NULL"}, + {ERR_COMMAND_NOT_FOUND, "Command not found"}, + {ERR_FORMAT_INVALID, "Invalid format parameter"}, + {ERR_BUFF_SIZE_INVALID, "Invalid buffer size, buffer size should be more than 0 and less than " + + to_string(MAX_BUFFER_SIZE)}, + {ERR_COMMAND_INVALID, "Invalid command, only one control command can be executed each time"}, + {ERR_KMSG_SWITCH_VALUE_INVALID, "Invalid kmsg switch value, valid:on/off"} }; -using SwitchCache = CacheData; -using LogLevelCache = CacheData; - - -void PropertyGet(const string &key, char *value, int len) +string GetErrorStr(ErrorCode errorCode) { - if (len > HILOG_PROP_VALUE_MAX) { - std::cerr << "PropertyGet(): len exceed maximum.\n"; - return; - } - - auto handle = FindParameter(key.c_str()); - if (handle == -1) { - return; - } - - auto res = GetParameterValue(handle, value, len); - if (res < 0) { - std::cerr << "PropertyGet() -> GetParameterValue -> Can't get value for key: " << key; - std::cerr << " handle: " << handle << " Result: " << res << "\n"; - } + string def = "Unknown error code"; + return "[ERR_CODE: " + to_string(errorCode) + "] " + + FindValueByKey(g_ErrorMsg, (uint16_t)errorCode, def); } -void PropertySet(const string &key, const char* value) +static const unordered_map g_LogTypes { - auto len = value ? strlen(value) : 0; - if (len > HILOG_PROP_VALUE_MAX) { - std::cerr << "PropertyGet(): len exceed maximum.\n"; - return; - } - - auto result = SetParameter(key.c_str(), value); - if (result < 0) { - if (result == EC_INVALID) { - std::cerr << "PropertySet(): Invalid arguments.\n"; - } else { - std::cerr << "PropertySet(): Error: " << result << "\n"; - } - } -} + {LOG_INIT, "init"}, {LOG_CORE, "core"}, + {LOG_APP, "app"}, {LOG_KMSG, "kmsg"} +}; -string GetProgName() +uint16_t GetLogTypeByStr(const string& logTypeStr) { -#ifdef HILOG_USE_MUSL - return program_invocation_short_name; /* use HOS interface */ -#else - return getprogname(); -#endif + uint16_t def = LOG_TYPE_MAX; + return FindKeyByValue(g_LogTypes, logTypeStr, LOG_TYPE_MAX, StringCmp); } -string GetPropertyName(uint32_t propType) +static const unordered_map g_LogLevels { - 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_KMSG: - key = "persist.sys.hilog.kmsg.on"; - break; - case PROP_PERSIST_DEBUG: - key = "persist.sys.hilog.debug.on"; - break; - default: - break; - } - return key; -} - -static int LockByProp(uint32_t propType) + {LOG_DEBUG, "debug"}, {LOG_INFO, "info"}, + {LOG_WARN, "warn"}, {LOG_ERROR, "error"}, + {LOG_FATAL, "fatal"} +}; +static bool LogLevelStrCmp(const std::string& l1, const std::string& l2) { - 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_KMSG: - return pthread_mutex_trylock(&g_kmsgLock); - case PROP_PERSIST_DEBUG: - return pthread_mutex_trylock(&g_persistDebugLock); - default: - return -1; + if(l1.length() == 1 && std::tolower(l1[0]) == std::tolower(l2[0])) { + return true; + } else if(l1.length() == l2.length()) { + return std::equal(l1.begin(), l1.end(), l2.begin(), + [](char a, char b) { + return std::tolower(a) == std::tolower(b); + }); + } else { + return false; } } -static void UnlockByProp(uint32_t propType) +uint16_t GetLogLevel(const std::string& logLevelStr) { - 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_KMSG: - pthread_mutex_unlock(&g_kmsgLock); - break; - case PROP_PERSIST_DEBUG: - pthread_mutex_unlock(&g_persistDebugLock); - break; - default: - break; - } + uint16_t def = 0; + return FindKeyByValue(g_LogLevels, logLevelStr, 0, LogLevelStrCmp); } -static bool textToBool(const RawPropertyData& data, bool defaultVal) +static const unordered_map g_CompressAlgos { - if (!strcmp(data.data(), "true")) { - return true; - } else if (!strcmp(data.data(), "false")) { - return false; - } - return defaultVal; -} + {COMPRESS_TYPE_NONE, "none"}, {COMPRESS_TYPE_ZLIB, "zlib"}, {COMPRESS_TYPE_ZSTD, "zstd"} +}; -bool IsDebugOn() +uint16_t GetCompressAlg(const std::string& alg) { - return IsSingleDebugOn() || IsPersistDebugOn(); + uint16_t def = COMPRESS_TYPE_ZLIB; + return FindKeyByValue(g_CompressAlgos, alg, def, StringCmp); } -bool IsSingleDebugOn() +uint64_t GetBuffSize(const string& buffSizeStr) { - static auto *switchCache = new SwitchCache(textToBool, false, PROP_SINGLE_DEBUG); - return switchCache->getValue(); + uint64_t index = buffSizeStr.size() - 1; + uint64_t buffSize; + std::regex reg("[0-9]+[bBkKmMgGtT]?"); + if (!std::regex_match(buffSizeStr, reg)) { + std::cout << ParseErrorCode(ERR_BUFF_SIZE_INVALID) << std::endl; + exit(-1); + } + if (buffSizeStr[index] == 'b' || buffSizeStr[index] == 'B') { + buffSize = stol(buffSizeStr.substr(0, index)); + } else if (buffSizeStr[index] == 'k' || buffSizeStr[index] == 'K') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_KB; + } else if (buffSizeStr[index] == 'm' || buffSizeStr[index] == 'M') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_MB; + } else if (buffSizeStr[index] == 'g' || buffSizeStr[index] == 'G') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_GB; + } else if (buffSizeStr[index] == 't' || buffSizeStr[index] == 'T') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_TB; + } else { + buffSize = stol(buffSizeStr.substr(0, index + 1)); + } + return buffSize; } -bool IsPersistDebugOn() + + +string SetDefaultLogType(const std::string& logTypeStr) { - static auto *switchCache = new SwitchCache(textToBool, false, PROP_PERSIST_DEBUG); - return switchCache->getValue(); + string logType; + if (logTypeStr == "") { + logType = "core app"; + } else if (logTypeStr == "all") { + logType = "core app init"; + } else { + logType = logTypeStr; + } + return logType; } -bool IsPrivateSwitchOn() + +using hash_t = std::uint64_t; +hash_t Hash(char const *str) { - static auto *switchCache = new SwitchCache(textToBool, true, PROP_PRIVATE); - return switchCache->getValue(); + hash_t ret {BASIS}; + while (*str) { + ret ^= *str; + ret *= PRIME; + str++; + } + return ret; } -bool IsProcessSwitchOn() +constexpr hash_t HashCompileTime(char const *str, hash_t lastValue = BASIS) { - static auto *switchCache = new SwitchCache(textToBool, false, PROP_PROCESS_FLOWCTRL); - return switchCache->getValue(); + return *str ? HashCompileTime(str + 1, (*str ^ lastValue) * PRIME) : lastValue; } -bool IsDomainSwitchOn() +constexpr unsigned long long operator "" _hash(char const *p, size_t) { - static auto *switchCache = new SwitchCache(textToBool, false, PROP_DOMAIN_FLOWCTRL); - return switchCache->getValue(); + return HashCompileTime(p); } -bool IsKmsgSwitchOn() +static string GetLogTypeStr(uint16_t logType) { - static auto *switchCache = new SwitchCache(textToBool, false, PROP_KMSG); - return switchCache->getValue(); + auto it = g_LogTypes.find(logType); + return (it != g_LogTypes.end()) ? it->second : "invalid"; } -static uint16_t textToLogLevel(const RawPropertyData& data, uint16_t defaultVal) +static string GetLogTypeComboStr(uint16_t shiftType) { - static const std::unordered_map logLevels = { - { 'd', LOG_DEBUG }, { 'D', LOG_DEBUG }, - { 'i', LOG_INFO }, { 'I', LOG_INFO }, - { 'w', LOG_WARN }, { 'W', LOG_WARN }, - { 'e', LOG_ERROR }, { 'E', LOG_ERROR }, - { 'f', LOG_FATAL }, { 'F', LOG_FATAL }, - }; - auto it = logLevels.find(data[0]); - if (it != logLevels.end()) { - return it->second; + LogType types[] = {LOG_INIT, LOG_CORE, LOG_APP, LOG_KMSG}; + string str=""; + uint16_t typeAll = 0; + + for(LogType t: types) { + typeAll |= (1 << t); } - return LOG_LEVEL_MIN; + shiftType &= typeAll; + for(LogType t: types) { + if ((1 << t) & shiftType) { + str += GetLogTypeStr(t); + shiftType &= (~(1 << t)); + } + if (shiftType != 0) { + str +","; + } else { + break; + } + } + return str; } -uint16_t GetGlobalLevel() +static string GetPressAlgStr(uint16_t pressAlg) { - static auto *logLevelCache = new LogLevelCache(textToLogLevel, LOG_LEVEL_MIN, PROP_GLOBAL_LOG_LEVEL); - return logLevelCache->getValue(); + string pressAlgStr = "none"; + if (pressAlg == COMPRESS_TYPE_ZSTD) { + pressAlgStr = "zstd"; + } else if (pressAlg == COMPRESS_TYPE_ZLIB) { + pressAlgStr = "zlib"; + } + return pressAlgStr; } -uint16_t GetDomainLevel(uint32_t domain) +static string GetByteLenStr(uint64_t buffSize) { - static auto *domainMap = new std::unordered_map(); - static shared_timed_mutex* mtx = new shared_timed_mutex; - std::decay::type::iterator it; - { - ReadLock lock(*mtx); - it = domainMap->find(domain); + string buffSizeStr; + if (buffSize < ONE_KB) { + buffSizeStr += to_string(buffSize); + buffSizeStr += "B"; + } else if (buffSize < ONE_MB) { + buffSize = buffSize / ONE_KB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "K"; + } else if (buffSize < ONE_GB) { + buffSize = buffSize / ONE_MB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "M"; + } else if (buffSize < ONE_TB) { + buffSize = buffSize / ONE_GB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "G"; + } else { + buffSize = buffSize / ONE_TB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "T"; } - if (it == domainMap->end()) { // new domain - InsertLock lock(*mtx); - it = domainMap->find(domain); // secured for two thread went across above condition - if (it == domainMap->end()) { - LogLevelCache* levelCache = new LogLevelCache(textToLogLevel, LOG_LEVEL_MIN, PROP_DOMAIN_LOG_LEVEL, - to_string(domain)); - auto result = domainMap->insert({ domain, levelCache }); - if (!result.second) { - std::cerr << "Can't insert new LogLevelCache for domain: " << domain << "\n"; - return LOG_LEVEL_MIN; - } - it = result.first; - } - } - LogLevelCache* levelCache = it->second; - return levelCache->getValue(); + return buffSizeStr; } -uint16_t GetTagLevel(const string& tag) +void Split(const std::string& src, const std::string& separator, std::vector& dest) { - static auto *tagMap = new std::unordered_map(); - static shared_timed_mutex* mtx = new shared_timed_mutex; - std::decay::type::iterator it; - { - ReadLock lock(*mtx); - it = tagMap->find(tag); + string str = src; + string substring; + string::size_type start = 0; + string::size_type index; + dest.clear(); + index = str.find_first_of(separator, start); + if (index == string::npos) { + dest.push_back(str); + return; } - if (it == tagMap->end()) { // new tag - InsertLock lock(*mtx); - it = tagMap->find(tag); // secured for two thread went across above condition - if (it == tagMap->end()) { - LogLevelCache* levelCache = new LogLevelCache(textToLogLevel, LOG_LEVEL_MIN, PROP_TAG_LOG_LEVEL, tag); - auto result = tagMap->insert({ tag, levelCache }); - if (!result.second) { - std::cerr << "Can't insert new LogLevelCache for tag: " << tag << "\n"; - return LOG_LEVEL_MIN; - } - it = result.first; + do { + substring = str.substr(start, index - start); + dest.push_back(substring); + start = index + separator.size(); + index = str.find(separator, start); + if (start == string::npos) { + break; } - } - LogLevelCache* levelCache = it->second; - return levelCache->getValue(); + } while (index != string::npos); + substring = str.substr(start); + dest.emplace_back(substring); } + +} // namespace HiviewDFX +} // namespace OHOS \ No newline at end of file diff --git a/adapter/properties.h b/adapter/properties.h index 12d2e5d..e5ec8dc 100644 --- a/adapter/properties.h +++ b/adapter/properties.h @@ -20,25 +20,10 @@ #include #include -static const int HILOG_PROP_VALUE_MAX = 92; +#include -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_KMSG, - 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(); bool IsSingleDebugOn(); bool IsPersistDebugOn(); @@ -47,6 +32,19 @@ bool IsProcessSwitchOn(); bool IsDomainSwitchOn(); bool IsKmsgSwitchOn(); uint16_t GetGlobalLevel(); +uint16_t GetTagLevel(const std::string& tag); uint16_t GetDomainLevel(uint32_t domain); -#endif +int SetSingleDebugOn(bool on); +int SetPersistDebugOn(bool on); +int SetPrivateSwitchOn(bool on); +int SetProcessSwitchOn(bool on); +int SetDomainSwitchOn(bool on); +int SetKmsgSwitchOn(bool on); +int SetGlobalLevel(LogLevel lvl); +int SetTagLevel(const std::string& tag, LogLevel lvl); +int SetDomainLevel(uint32_t domain, LogLevel lvl); + +std::string Int2HexStr(int i); +int HexStr2Int(const std::string& str); +#endif \ No newline at end of file diff --git a/services/hilogtool/include/log_utils.h b/services/hilogtool/include/log_utils.h new file mode 100644 index 0000000..9461bef --- /dev/null +++ b/services/hilogtool/include/log_utils.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef LOG_UTILS_H +#define LOG_UTILS_H + +#include +#include + +namespace OHOS { +namespace HiviewDFX { + +void Split(const std::string& src, const std::string& separator, std::vector& dest); +uint16_t GetLogTypeByStr(const string& logTypeStr); + +} // namespace HiviewDFX +} // namespace OHOS +#endif // LOG_UTILS_H \ No newline at end of file diff --git a/services/hilogtool/log_controller.cpp b/services/hilogtool/log_controller.cpp index cb27e04..3112dc1 100644 --- a/services/hilogtool/log_controller.cpp +++ b/services/hilogtool/log_controller.cpp @@ -48,118 +48,6 @@ void SetMsgHead(MessageHeader* msgHeader, const uint8_t msgCmd, const uint16_t m msgHeader->msgLen = msgLen; } -void Split(const std::string& src, const std::string& separator, std::vector& dest) -{ - string str = src; - string substring; - string::size_type start = 0; - string::size_type index; - dest.clear(); - index = str.find_first_of(separator, start); - if (index == string::npos) { - dest.push_back(str); - return; - } - do { - substring = str.substr(start, index - start); - dest.push_back(substring); - start = index + separator.size(); - index = str.find(separator, start); - if (start == string::npos) { - break; - } - } while (index != string::npos); - substring = str.substr(start); - dest.emplace_back(substring); -} - -uint16_t GetLogType(const string& logTypeStr) -{ - uint16_t logType; - if (logTypeStr == "init") { - logType = LOG_INIT; - } else if (logTypeStr == "core") { - logType = LOG_CORE; - } else if (logTypeStr == "app") { - logType = LOG_APP; - } else if (logTypeStr == "kmsg") { - logType = LOG_KMSG; - } else { - return 0xffff; - } - return logType; -} - -uint64_t GetBuffSize(const string& buffSizeStr) -{ - uint64_t index = buffSizeStr.size() - 1; - uint64_t buffSize; - std::regex reg("[0-9]+[bBkKmMgGtT]?"); - if (!std::regex_match(buffSizeStr, reg)) { - std::cout << ParseErrorCode(ERR_BUFF_SIZE_INVALID) << std::endl; - exit(-1); - } - if (buffSizeStr[index] == 'b' || buffSizeStr[index] == 'B') { - buffSize = stol(buffSizeStr.substr(0, index)); - } else if (buffSizeStr[index] == 'k' || buffSizeStr[index] == 'K') { - buffSize = stol(buffSizeStr.substr(0, index)) * ONE_KB; - } else if (buffSizeStr[index] == 'm' || buffSizeStr[index] == 'M') { - buffSize = stol(buffSizeStr.substr(0, index)) * ONE_MB; - } else if (buffSizeStr[index] == 'g' || buffSizeStr[index] == 'G') { - buffSize = stol(buffSizeStr.substr(0, index)) * ONE_GB; - } else if (buffSizeStr[index] == 't' || buffSizeStr[index] == 'T') { - buffSize = stol(buffSizeStr.substr(0, index)) * ONE_TB; - } else { - buffSize = stol(buffSizeStr.substr(0, index + 1)); - } - return buffSize; -} - -uint16_t GetCompressAlg(const std::string& pressAlg) -{ - if (pressAlg == "none") { - return COMPRESS_TYPE_NONE; - } else if (pressAlg == "zlib") { - return COMPRESS_TYPE_ZLIB; - } else if (pressAlg == "zstd") { - return COMPRESS_TYPE_ZSTD; - } - return COMPRESS_TYPE_ZLIB; -} - -uint16_t GetLogLevel(const std::string& logLevelStr, std::string& logLevel) -{ - if (logLevelStr == "debug" || logLevelStr == "DEBUG" || logLevelStr == "d" || logLevelStr == "D") { - logLevel = "D"; - return LOG_DEBUG; - } else if (logLevelStr == "info" || logLevelStr == "INFO" || logLevelStr == "i" || logLevelStr == "I") { - logLevel = "I"; - return LOG_INFO; - } else if (logLevelStr == "warn" || logLevelStr == "WARN" || logLevelStr == "w" || logLevelStr == "W") { - logLevel = "W"; - return LOG_WARN; - } else if (logLevelStr == "error" || logLevelStr == "ERROR" || logLevelStr == "e" || logLevelStr == "E") { - logLevel = "E"; - return LOG_ERROR; - } else if (logLevelStr == "fatal" || logLevelStr == "FATAL" || logLevelStr == "f" || logLevelStr == "F") { - logLevel = "F"; - return LOG_FATAL; - } - return 0xffff; -} - -string SetDefaultLogType(const std::string& logTypeStr) -{ - string logType; - if (logTypeStr == "") { - logType = "core app"; - } else if (logTypeStr == "all") { - logType = "core app init"; - } else { - logType = logTypeStr; - } - return logType; -} void NextRequestOp(SeqPacketSocketClient& controller, uint16_t sendId) { NextRequest nextRequest = {{0}}; @@ -506,6 +394,7 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType vector vecTag; uint32_t domainNum, tagNum; uint32_t iter; + int ret = RET_SUCCESS; string key, value; Split(propertyParm->domainStr, " ", vecDomain); Split(propertyParm->tagStr, " ", vecTag); @@ -513,12 +402,11 @@ 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(key.c_str(), "true"); + ret = SetPrivateSwitchOn(true); cout << "hilog private formatter is enabled" << endl; } else if (propertyParm->privateSwitchStr == "off") { - PropertySet(key.c_str(), "false"); + ret = SetPrivateSwitchOn(false); cout << "hilog private formatter is disabled" << endl; } else { cout << ParseErrorCode(ERR_PRIVATE_SWITCH_VALUE_INVALID) << endl; @@ -526,12 +414,11 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType } break; case OT_KMSG_SWITCH: - key = GetPropertyName(PROP_KMSG); if (propertyParm->kmsgSwitchStr == "on") { - PropertySet(key.c_str(), "true"); + ret = SetKmsgSwitchOn(true); std::cout << "hilog will store kmsg log" << std::endl; } else if (propertyParm->kmsgSwitchStr == "off") { - PropertySet(key.c_str(), "false"); + ret = SetKmsgSwitchOn(false); std::cout << "hilog will not store kmsg log" << std::endl; } else { std::cout << ParseErrorCode(ERR_KMSG_SWITCH_VALUE_INVALID) << std::endl; @@ -542,51 +429,48 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType if (propertyParm->tagStr != "" && propertyParm->domainStr != "") { return RET_FAIL; } else if (propertyParm->domainStr != "") { // by domain - std::string keyPre = GetPropertyName(PROP_DOMAIN_LOG_LEVEL); for (iter = 0; iter < domainNum; iter++) { - key = keyPre + vecDomain[iter]; - if (GetLogLevel(propertyParm->logLevelStr, value) == 0xffff) { - continue; + char *end; + uint16_t lvl = GetLogLevel(propertyParm->logLevelStr, value); + if (lvl== UINT16_MAX) { + return RET_FAIL; } - PropertySet(key.c_str(), value.c_str()); + ret = SetDomainLevel(HexStr2Int(vecDomain[iter]), lvl); + if(ret != RET_SUCCESS) break; 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 = keyPre + vecTag[iter]; - if (GetLogLevel(propertyParm->logLevelStr, value) == 0xffff) { - continue; + uint16_t lvl = GetLogLevel(propertyParm->logLevelStr, value); + if (lvl== UINT16_MAX) { + return RET_FAIL; } - PropertySet(key.c_str(), value.c_str()); + ret = SetTagLevel(vecTag[iter].c_str(), lvl); + if(ret != RET_SUCCESS) break; cout << "tag " << vecTag[iter] << " level is set to " << propertyParm->logLevelStr << endl; } } else { - key = GetPropertyName(PROP_GLOBAL_LOG_LEVEL); - if (GetLogLevel(propertyParm->logLevelStr, value) == 0xffff) { - return RET_FAIL; - } - PropertySet(key.c_str(), value.c_str()); - cout << "global log level is set to " << propertyParm->logLevelStr << endl; + LogLevel lvl = GetLogLevel(propertyParm->logLevelStr, value); + if (lvl== UINT16_MAX) { + return RET_FAIL; + } + ret = SetGlobalLevel(lvl); + cout << "global log level is set to " << propertyParm->logLevelStr << endl; } break; case OT_FLOW_SWITCH: if (propertyParm->flowSwitchStr == "pidon") { - key = GetPropertyName(PROP_PROCESS_FLOWCTRL); - PropertySet(key.c_str(), "true"); + ret = SetProcessSwitchOn(true); cout << "flow control by process is enabled" << endl; } else if (propertyParm->flowSwitchStr == "pidoff") { - key = GetPropertyName(PROP_PROCESS_FLOWCTRL); - PropertySet(key.c_str(), "false"); + ret = SetProcessSwitchOn(false); cout << "flow control by process is disabled" << endl; } else if (propertyParm->flowSwitchStr == "domainon") { - key = GetPropertyName(PROP_DOMAIN_FLOWCTRL); - PropertySet(key.c_str(), "true"); + ret = SetDomainSwitchOn(true); cout << "flow control by domain is enabled" << endl; } else if (propertyParm->flowSwitchStr == "domainoff") { - key = GetPropertyName(PROP_DOMAIN_FLOWCTRL); - PropertySet(key.c_str(), "false"); + ret = SetDomainSwitchOn(false); cout << "flow control by domain is disabled" << endl; } else { cout << ParseErrorCode(ERR_FLOWCTRL_SWITCH_VALUE_INVALID) << endl; @@ -597,10 +481,9 @@ int32_t SetPropertiesOp(SeqPacketSocketClient& controller, uint8_t operationType default: break; } - return RET_SUCCESS; + return ret != RET_SUCCESS ? RET_FAIL : RET_SUCCESS; } - int MultiQuerySplit(const std::string& src, const char& delim, std::vector& vecSplit) { int srcSize = src.length(); @@ -629,4 +512,4 @@ int MultiQuerySplit(const std::string& src, const char& delim, std::vector #include #include -#include #include "hilog/log.h" #include "format.h" #include "log_controller.h" @@ -28,149 +27,6 @@ namespace OHOS { namespace HiviewDFX { using namespace std; -using hash_t = std::uint64_t; -unordered_map errorMsg -{ - {RET_FAIL, "Unexpected error"}, - {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F"}, - {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg"}, - {ERR_QUERY_TYPE_INVALID, "Query condition on both types and excluded types is undefined or\ - queryTypes can not contain app/core/init and kmsg at the same time"}, - {ERR_QUERY_LEVEL_INVALID, "Query condition on both levels and excluded levels is undefined"}, - {ERR_QUERY_DOMAIN_INVALID, "Invalid domain format, a hexadecimal number is needed"}, - {ERR_QUERY_TAG_INVALID, "Query condition on both tags and excluded tags is undefined"}, - {ERR_QUERY_PID_INVALID, "Query condition on both pid and excluded pid is undefined"}, - {ERR_BUFF_SIZE_EXP, "Buffer resize exception"}, - {ERR_LOG_PERSIST_FILE_SIZE_INVALID, "Invalid log persist file size, file size should be not less than " - + to_string(MAX_PERSISTER_BUFFER_SIZE)}, - {ERR_LOG_PERSIST_FILE_NAME_INVALID, "Invalid log persist file name, file name should not contain [\\/:*?\"<>|]"}, - {ERR_LOG_PERSIST_COMPRESS_BUFFER_EXP, "Invalid Log persist compression buffer"}, - {ERR_LOG_PERSIST_FILE_PATH_INVALID, "Invalid persister file path or persister directory does not exist"}, - {ERR_LOG_PERSIST_COMPRESS_INIT_FAIL, "Log persist compression initialization failed"}, - {ERR_LOG_PERSIST_FILE_OPEN_FAIL, "Log persist open file failed"}, - {ERR_LOG_PERSIST_MMAP_FAIL, "Log persist mmap failed"}, - {ERR_LOG_PERSIST_JOBID_FAIL, "Log persist jobid not exist"}, - {ERR_LOG_PERSIST_TASK_FAIL, "Log persist task is existed"}, - {ERR_DOMAIN_INVALID, "Invalid domain, domain should not be more than 0 and less than " - + to_string(DOMAIN_MAX_SCOPE)}, - {ERR_MEM_ALLOC_FAIL, "Alloc memory failed"}, - {ERR_MSG_LEN_INVALID, "Invalid message length, message length should be not more than " - + to_string(MSG_MAX_LEN)}, - {ERR_PRIVATE_SWITCH_VALUE_INVALID, "Invalid private switch value, valid:on/off"}, - {ERR_FLOWCTRL_SWITCH_VALUE_INVALID, "Invalid flowcontrl switch value, valid:pidon/pidoff/domainon/domainoff"}, - {ERR_LOG_PERSIST_JOBID_INVALID, "Invalid jobid, jobid should be more than 0"}, - {ERR_LOG_CONTENT_NULL, "Log content NULL"}, - {ERR_COMMAND_NOT_FOUND, "Command not found"}, - {ERR_FORMAT_INVALID, "Invalid format parameter"}, - {ERR_BUFF_SIZE_INVALID, "Invalid buffer size, buffer size should be more than 0 and less than " - + to_string(MAX_BUFFER_SIZE)}, - {ERR_COMMAND_INVALID, "Invalid command, only one control command can be executed each time"}, - {ERR_KMSG_SWITCH_VALUE_INVALID, "Invalid kmsg switch value, valid:on/off"} -}; - -string ParseErrorCode(ErrorCode errorCode) -{ - if (errorMsg.count(errorCode) == 0) { - cout << "ERR_CODE not exist" << endl; - } - string errorMsgStr = "[ERR_CODE:" + to_string(errorCode) + "], " + errorMsg[errorCode]; - return errorMsgStr; -} - -hash_t Hash(char const *str) -{ - hash_t ret {BASIS}; - while (*str) { - ret ^= *str; - ret *= PRIME; - str++; - } - return ret; -} -constexpr hash_t HashCompileTime(char const *str, hash_t lastValue = BASIS) -{ - return *str ? HashCompileTime(str + 1, (*str ^ lastValue) * PRIME) : lastValue; -} -constexpr unsigned long long operator "" _hash(char const *p, size_t) -{ - return HashCompileTime(p); -} - -string GetLogTypeStr(uint16_t logType) -{ - string logTypeStr = "invalid"; - if (logType == LOG_INIT) { - logTypeStr = "init"; - } - if (logType == LOG_CORE) { - logTypeStr = "core"; - } - if (logType == LOG_APP) { - logTypeStr = "app"; - } - if (logType == LOG_KMSG) { - logTypeStr = "kmsg"; - } - return logTypeStr; -} - -string GetOrigType(uint16_t shiftType) -{ - string logType = ""; - if (((1 << LOG_INIT) & shiftType) != 0) { - logType += "init,"; - } - if (((1 << LOG_CORE) & shiftType) != 0) { - logType += "core,"; - } - if (((1 << LOG_APP) & shiftType) != 0) { - logType += "app,"; - } - if (((1 << LOG_KMSG) & shiftType) != 0) { - logType += "kmsg,"; - } - logType.erase(logType.end() - 1); - return logType; -} - -string GetPressAlgStr(uint16_t pressAlg) -{ - string pressAlgStr; - if (pressAlg == COMPRESS_TYPE_ZSTD) { - pressAlgStr = "zstd"; - } - if (pressAlg == COMPRESS_TYPE_ZLIB) { - pressAlgStr = "zlib"; - } - return pressAlgStr; -} - -string GetByteLenStr(uint64_t buffSize) -{ - string buffSizeStr; - if (buffSize < ONE_KB) { - buffSizeStr += to_string(buffSize); - buffSizeStr += "B"; - } else if (buffSize < ONE_MB) { - buffSize = buffSize / ONE_KB; - buffSizeStr += to_string(buffSize); - buffSizeStr += "K"; - } else if (buffSize < ONE_GB) { - buffSize = buffSize / ONE_MB; - buffSizeStr += to_string(buffSize); - buffSizeStr += "M"; - } else if (buffSize < ONE_TB) { - buffSize = buffSize / ONE_GB; - buffSizeStr += to_string(buffSize); - buffSizeStr += "G"; - } else { - buffSize = buffSize / ONE_TB; - buffSizeStr += to_string(buffSize); - buffSizeStr += "T"; - } - return buffSizeStr; -} - /* * print control command operation result */ @@ -362,7 +218,7 @@ int32_t ControlCmdResult(const char* message) } else { outputStr += to_string(pLogPersistQueryRst->jobId); outputStr += " "; - outputStr += GetOrigType(pLogPersistQueryRst->logType); + outputStr += GetLogTypeComboStr(pLogPersistQueryRst->logType); outputStr += " "; outputStr += GetPressAlgStr(pLogPersistQueryRst->compressAlg); outputStr += " "; @@ -390,36 +246,16 @@ HilogShowFormat HilogFormat (const char* formatArg) static HilogShowFormat format; switch (Hash(formatArg)) { - case "color"_hash: - format = COLOR_SHOWFORMAT; - break; - case "colour"_hash: - format = COLOR_SHOWFORMAT; - break; - case "time"_hash: - format = TIME_SHOWFORMAT; - break; - case "usec"_hash: - format = TIME_USEC_SHOWFORMAT; - break; - case "nsec"_hash: - format = TIME_NSEC_SHOWFORMAT; - break; - case "year"_hash: - format = YEAR_SHOWFORMAT; - break; - case "zone"_hash: - format = ZONE_SHOWFORMAT; - break; - case "epoch"_hash: - format = EPOCH_SHOWFORMAT; - break; - case "monotonic"_hash: - format = MONOTONIC_SHOWFORMAT; - break; - default: - cout << ParseErrorCode(ERR_FORMAT_INVALID) << endl; - exit(1); + case "color"_hash: format = COLOR_SHOWFORMAT; break; + case "colour"_hash: format = COLOR_SHOWFORMAT; break; + case "time"_hash: format = TIME_SHOWFORMAT; break; + case "usec"_hash: format = TIME_USEC_SHOWFORMAT; break; + case "nsec"_hash: format = TIME_NSEC_SHOWFORMAT; break; + case "year"_hash: format = YEAR_SHOWFORMAT; break; + case "zone"_hash: format = ZONE_SHOWFORMAT; break; + case "epoch"_hash: format = EPOCH_SHOWFORMAT; break; + case "monotonic"_hash: format = MONOTONIC_SHOWFORMAT; break; + default: cout << ParseErrorCode(ERR_FORMAT_INVALID) << endl; exit(1); } return format; } @@ -511,4 +347,4 @@ void HilogShowLog(uint32_t showFormat, HilogDataMessage* data, const HilogArgs* return; } } // namespace HiviewDFX -} // namespace OHOS +} // namespace OHOS \ No newline at end of file diff --git a/services/hilogtool/log_utils.cpp b/services/hilogtool/log_utils.cpp new file mode 100644 index 0000000..d935d6c --- /dev/null +++ b/services/hilogtool/log_utils.cpp @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include +#include "log_utils.h" +#include "hilog_common.h" +#include "hilogtool_msg.h" + +namespace OHOS { +namespace HiviewDFX { +using namespace std; + + +template +static V FindValueByKey(std::unordered_map map, K key, V& def) +{ + auto it = map.find(key); + return it == map.end() ? def : it->second; +} + +static bool StringCmp(std::string& s1, std::string& s2) +{ + return s1 == s2; +} + +template +static K FindKeyByValue(std::unordered_map map, V& value, K def, std::function cmp) +{ + auto it = map.begin(); + + for(auto it = map.begin(); it == map.end(); it++) { + if (cmp(it->second, value)) { + return it->first; + } + } + return def; +} + + +static const unordered_map g_ErrorMsg +{ + {RET_FAIL, "Unexpected error"}, + {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F"}, + {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg"}, + {ERR_QUERY_TYPE_INVALID, "Query condition on both types and excluded types is undefined or\ + queryTypes can not contain app/core/init and kmsg at the same time"}, + {ERR_QUERY_LEVEL_INVALID, "Query condition on both levels and excluded levels is undefined"}, + {ERR_QUERY_DOMAIN_INVALID, "Invalid domain format, a hexadecimal number is needed"}, + {ERR_QUERY_TAG_INVALID, "Query condition on both tags and excluded tags is undefined"}, + {ERR_QUERY_PID_INVALID, "Query condition on both pid and excluded pid is undefined"}, + {ERR_BUFF_SIZE_EXP, "Buffer resize exception"}, + {ERR_LOG_PERSIST_FILE_SIZE_INVALID, "Invalid log persist file size, file size should be not less than " + + to_string(MAX_PERSISTER_BUFFER_SIZE)}, + {ERR_LOG_PERSIST_FILE_NAME_INVALID, "Invalid log persist file name, file name should not contain [\\/:*?\"<>|]"}, + {ERR_LOG_PERSIST_COMPRESS_BUFFER_EXP, "Invalid Log persist compression buffer"}, + {ERR_LOG_PERSIST_FILE_PATH_INVALID, "Invalid persister file path or persister directory does not exist"}, + {ERR_LOG_PERSIST_COMPRESS_INIT_FAIL, "Log persist compression initialization failed"}, + {ERR_LOG_PERSIST_FILE_OPEN_FAIL, "Log persist open file failed"}, + {ERR_LOG_PERSIST_MMAP_FAIL, "Log persist mmap failed"}, + {ERR_LOG_PERSIST_JOBID_FAIL, "Log persist jobid not exist"}, + {ERR_LOG_PERSIST_TASK_FAIL, "Log persist task is existed"}, + {ERR_DOMAIN_INVALID, "Invalid domain, domain should not be more than 0 and less than " + + to_string(DOMAIN_MAX_SCOPE)}, + {ERR_MEM_ALLOC_FAIL, "Alloc memory failed"}, + {ERR_MSG_LEN_INVALID, "Invalid message length, message length should be not more than " + + to_string(MSG_MAX_LEN)}, + {ERR_PRIVATE_SWITCH_VALUE_INVALID, "Invalid private switch value, valid:on/off"}, + {ERR_FLOWCTRL_SWITCH_VALUE_INVALID, "Invalid flowcontrl switch value, valid:pidon/pidoff/domainon/domainoff"}, + {ERR_LOG_PERSIST_JOBID_INVALID, "Invalid jobid, jobid should be more than 0"}, + {ERR_LOG_CONTENT_NULL, "Log content NULL"}, + {ERR_COMMAND_NOT_FOUND, "Command not found"}, + {ERR_FORMAT_INVALID, "Invalid format parameter"}, + {ERR_BUFF_SIZE_INVALID, "Invalid buffer size, buffer size should be more than 0 and less than " + + to_string(MAX_BUFFER_SIZE)}, + {ERR_COMMAND_INVALID, "Invalid command, only one control command can be executed each time"}, + {ERR_KMSG_SWITCH_VALUE_INVALID, "Invalid kmsg switch value, valid:on/off"} +}; + +string GetErrorStr(ErrorCode errorCode) +{ + string def = "Unknown error code"; + return "[ERR_CODE: " + to_string(errorCode) + "] " + + FindValueByKey(g_ErrorMsg, (uint16_t)errorCode, def); +} + +static const unordered_map g_LogTypes +{ + {LOG_INIT, "init"}, {LOG_CORE, "core"}, + {LOG_APP, "app"}, {LOG_KMSG, "kmsg"} +}; + +uint16_t GetLogTypeByStr(const string& logTypeStr) +{ + uint16_t def = LOG_TYPE_MAX; + return FindKeyByValue(g_LogTypes, logTypeStr, LOG_TYPE_MAX, StringCmp); +} + +static const unordered_map g_LogLevels +{ + {LOG_DEBUG, "debug"}, {LOG_INFO, "info"}, + {LOG_WARN, "warn"}, {LOG_ERROR, "error"}, + {LOG_FATAL, "fatal"} +}; +static bool LogLevelStrCmp(const std::string& l1, const std::string& l2) +{ + if(l1.length() == 1 && std::tolower(l1[0]) == std::tolower(l2[0])) { + return true; + } else if(l1.length() == l2.length()) { + return std::equal(l1.begin(), l1.end(), l2.begin(), + [](char a, char b) { + return std::tolower(a) == std::tolower(b); + }); + } else { + return false; + } +} + +uint16_t GetLogLevel(const std::string& logLevelStr) +{ + uint16_t def = 0; + return FindKeyByValue(g_LogLevels, logLevelStr, 0, LogLevelStrCmp); +} + +static const unordered_map g_CompressAlgos +{ + {COMPRESS_TYPE_NONE, "none"}, {COMPRESS_TYPE_ZLIB, "zlib"}, {COMPRESS_TYPE_ZSTD, "zstd"} +}; + +uint16_t GetCompressAlg(const std::string& alg) +{ + uint16_t def = COMPRESS_TYPE_ZLIB; + return FindKeyByValue(g_CompressAlgos, alg, def, StringCmp); +} + +uint64_t GetBuffSize(const string& buffSizeStr) +{ + uint64_t index = buffSizeStr.size() - 1; + uint64_t buffSize; + std::regex reg("[0-9]+[bBkKmMgGtT]?"); + if (!std::regex_match(buffSizeStr, reg)) { + std::cout << ParseErrorCode(ERR_BUFF_SIZE_INVALID) << std::endl; + exit(-1); + } + if (buffSizeStr[index] == 'b' || buffSizeStr[index] == 'B') { + buffSize = stol(buffSizeStr.substr(0, index)); + } else if (buffSizeStr[index] == 'k' || buffSizeStr[index] == 'K') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_KB; + } else if (buffSizeStr[index] == 'm' || buffSizeStr[index] == 'M') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_MB; + } else if (buffSizeStr[index] == 'g' || buffSizeStr[index] == 'G') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_GB; + } else if (buffSizeStr[index] == 't' || buffSizeStr[index] == 'T') { + buffSize = stol(buffSizeStr.substr(0, index)) * ONE_TB; + } else { + buffSize = stol(buffSizeStr.substr(0, index + 1)); + } + return buffSize; +} + + + +string SetDefaultLogType(const std::string& logTypeStr) +{ + string logType; + if (logTypeStr == "") { + logType = "core app"; + } else if (logTypeStr == "all") { + logType = "core app init"; + } else { + logType = logTypeStr; + } + return logType; +} + + +using hash_t = std::uint64_t; +hash_t Hash(char const *str) +{ + hash_t ret {BASIS}; + while (*str) { + ret ^= *str; + ret *= PRIME; + str++; + } + return ret; +} + +constexpr hash_t HashCompileTime(char const *str, hash_t lastValue = BASIS) +{ + return *str ? HashCompileTime(str + 1, (*str ^ lastValue) * PRIME) : lastValue; +} + +constexpr unsigned long long operator "" _hash(char const *p, size_t) +{ + return HashCompileTime(p); +} + +static string GetLogTypeStr(uint16_t logType) +{ + auto it = g_LogTypes.find(logType); + return (it != g_LogTypes.end()) ? it->second : "invalid"; +} + +static string GetLogTypeComboStr(uint16_t shiftType) +{ + LogType types[] = {LOG_INIT, LOG_CORE, LOG_APP, LOG_KMSG}; + string str=""; + uint16_t typeAll = 0; + + for(LogType t: types) { + typeAll |= (1 << t); + } + shiftType &= typeAll; + for(LogType t: types) { + if ((1 << t) & shiftType) { + str += GetLogTypeStr(t); + shiftType &= (~(1 << t)); + } + if (shiftType != 0) { + str +","; + } else { + break; + } + } + return str; +} + +static string GetPressAlgStr(uint16_t pressAlg) +{ + string pressAlgStr = "none"; + if (pressAlg == COMPRESS_TYPE_ZSTD) { + pressAlgStr = "zstd"; + } else if (pressAlg == COMPRESS_TYPE_ZLIB) { + pressAlgStr = "zlib"; + } + return pressAlgStr; +} + +static string GetByteLenStr(uint64_t buffSize) +{ + string buffSizeStr; + if (buffSize < ONE_KB) { + buffSizeStr += to_string(buffSize); + buffSizeStr += "B"; + } else if (buffSize < ONE_MB) { + buffSize = buffSize / ONE_KB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "K"; + } else if (buffSize < ONE_GB) { + buffSize = buffSize / ONE_MB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "M"; + } else if (buffSize < ONE_TB) { + buffSize = buffSize / ONE_GB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "G"; + } else { + buffSize = buffSize / ONE_TB; + buffSizeStr += to_string(buffSize); + buffSizeStr += "T"; + } + return buffSizeStr; +} + +void Split(const std::string& src, const std::string& separator, std::vector& dest) +{ + string str = src; + string substring; + string::size_type start = 0; + string::size_type index; + dest.clear(); + index = str.find_first_of(separator, start); + if (index == string::npos) { + dest.push_back(str); + return; + } + do { + substring = str.substr(start, index - start); + dest.push_back(substring); + start = index + separator.size(); + index = str.find(separator, start); + if (start == string::npos) { + break; + } + } while (index != string::npos); + substring = str.substr(start); + dest.emplace_back(substring); +} + +} // namespace HiviewDFX +} // namespace OHOS \ No newline at end of file -- Gitee