12498b56bSopenharmony_ci/*
22498b56bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
32498b56bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
42498b56bSopenharmony_ci * you may not use this file except in compliance with the License.
52498b56bSopenharmony_ci * You may obtain a copy of the License at
62498b56bSopenharmony_ci *
72498b56bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
82498b56bSopenharmony_ci *
92498b56bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
102498b56bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
112498b56bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
122498b56bSopenharmony_ci * See the License for the specific language governing permissions and
132498b56bSopenharmony_ci * limitations under the License.
142498b56bSopenharmony_ci */
152498b56bSopenharmony_ci#include <codecvt>
162498b56bSopenharmony_ci#include <cstdint>
172498b56bSopenharmony_ci#include <cstdlib>
182498b56bSopenharmony_ci#include <chrono>
192498b56bSopenharmony_ci#include <functional>
202498b56bSopenharmony_ci#include <regex>
212498b56bSopenharmony_ci#include <sstream>
222498b56bSopenharmony_ci#include <thread>
232498b56bSopenharmony_ci#include <fstream>
242498b56bSopenharmony_ci#include <fcntl.h>
252498b56bSopenharmony_ci#include <securec.h>
262498b56bSopenharmony_ci#include <hilog/log.h>
272498b56bSopenharmony_ci#include <unistd.h>
282498b56bSopenharmony_ci#include "hilog_common.h"
292498b56bSopenharmony_ci#include "hilog_cmd.h"
302498b56bSopenharmony_ci#include "log_utils.h"
312498b56bSopenharmony_ci
322498b56bSopenharmony_cinamespace {
332498b56bSopenharmony_ci    constexpr uint32_t ONE_KB = (1UL << 10);
342498b56bSopenharmony_ci    constexpr uint32_t ONE_MB = (1UL << 20);
352498b56bSopenharmony_ci    constexpr uint32_t ONE_GB = (1UL << 30);
362498b56bSopenharmony_ci    constexpr uint64_t ONE_TB = (1ULL << 40);
372498b56bSopenharmony_ci    constexpr uint32_t DOMAIN_MIN = DOMAIN_APP_MIN;
382498b56bSopenharmony_ci    constexpr uint32_t DOMAIN_MAX = DOMAIN_OS_MAX;
392498b56bSopenharmony_ci    constexpr int CMDLINE_PATH_LEN = 32;
402498b56bSopenharmony_ci    constexpr int CMDLINE_LEN = 128;
412498b56bSopenharmony_ci    constexpr int STATUS_PATH_LEN = 32;
422498b56bSopenharmony_ci    constexpr int STATUS_LEN = 1024;
432498b56bSopenharmony_ci    const std::string SH_NAMES[] = { "sh", "/bin/sh", "/system/bin/sh", "/xbin/sh", "/system/xbin/sh"};
442498b56bSopenharmony_ci}
452498b56bSopenharmony_ci
462498b56bSopenharmony_cinamespace OHOS {
472498b56bSopenharmony_cinamespace HiviewDFX {
482498b56bSopenharmony_ciusing namespace std;
492498b56bSopenharmony_ciusing namespace std::chrono;
502498b56bSopenharmony_ci
512498b56bSopenharmony_ci// Buffer Size&Char Map
522498b56bSopenharmony_cistatic const KVMap<char, uint64_t> g_SizeMap({
532498b56bSopenharmony_ci    {'B', 1}, {'K', ONE_KB}, {'M', ONE_MB},
542498b56bSopenharmony_ci    {'G', ONE_GB}, {'T', ONE_TB}
552498b56bSopenharmony_ci}, ' ', 0);
562498b56bSopenharmony_ci
572498b56bSopenharmony_cistring Size2Str(uint64_t size)
582498b56bSopenharmony_ci{
592498b56bSopenharmony_ci    string str;
602498b56bSopenharmony_ci    uint64_t unit = 1;
612498b56bSopenharmony_ci    switch (size) {
622498b56bSopenharmony_ci        case 0 ... ONE_KB - 1: unit = 1; break;
632498b56bSopenharmony_ci        case ONE_KB ... ONE_MB - 1: unit = ONE_KB; break;
642498b56bSopenharmony_ci        case ONE_MB ... ONE_GB - 1: unit = ONE_MB; break;
652498b56bSopenharmony_ci        case ONE_GB ... ONE_TB - 1: unit = ONE_GB; break;
662498b56bSopenharmony_ci        default: unit = ONE_TB; break;
672498b56bSopenharmony_ci    }
682498b56bSopenharmony_ci    float i = (static_cast<float>(size)) / unit;
692498b56bSopenharmony_ci    constexpr int len = 16;
702498b56bSopenharmony_ci    char buf[len] = { 0 };
712498b56bSopenharmony_ci    int ret = snprintf_s(buf, len,  len - 1, "%.1f", i);
722498b56bSopenharmony_ci    if (ret <= 0) {
732498b56bSopenharmony_ci        str = to_string(size);
742498b56bSopenharmony_ci    } else {
752498b56bSopenharmony_ci        str = buf;
762498b56bSopenharmony_ci    }
772498b56bSopenharmony_ci    return str + g_SizeMap.GetKey(unit);
782498b56bSopenharmony_ci}
792498b56bSopenharmony_ci
802498b56bSopenharmony_ciuint64_t Str2Size(const string& str)
812498b56bSopenharmony_ci{
822498b56bSopenharmony_ci    std::regex reg("[0-9]+[BKMGT]?");
832498b56bSopenharmony_ci    if (!std::regex_match(str, reg)) {
842498b56bSopenharmony_ci        return 0;
852498b56bSopenharmony_ci    }
862498b56bSopenharmony_ci    uint64_t index = str.size() - 1;
872498b56bSopenharmony_ci    uint64_t unit = g_SizeMap.GetValue(str[index]);
882498b56bSopenharmony_ci
892498b56bSopenharmony_ci    uint64_t value = stoull(str.substr(0, unit !=0 ? index : index + 1));
902498b56bSopenharmony_ci    return value * (unit != 0 ? unit : 1);
912498b56bSopenharmony_ci}
922498b56bSopenharmony_ci
932498b56bSopenharmony_ci// Error Codes&Strings Map
942498b56bSopenharmony_cistatic const KVMap<int16_t, string> g_ErrorMsgs({
952498b56bSopenharmony_ci    {RET_SUCCESS, "Success"},
962498b56bSopenharmony_ci    {RET_FAIL, "Unknown failure reason"},
972498b56bSopenharmony_ci    {ERR_LOG_LEVEL_INVALID, "Invalid log level, the valid log levels include D/I/W/E/F"
982498b56bSopenharmony_ci    " or DEBUG/INFO/WARN/ERROR/FATAL"},
992498b56bSopenharmony_ci    {ERR_LOG_TYPE_INVALID, "Invalid log type, the valid log types include app/core/init/kmsg/only_prerelease"},
1002498b56bSopenharmony_ci    {ERR_INVALID_RQST_CMD, "Invalid request cmd, please check sourcecode"},
1012498b56bSopenharmony_ci    {ERR_QUERY_TYPE_INVALID, "Can't query kmsg type logs combined with other types logs."},
1022498b56bSopenharmony_ci    {ERR_INVALID_DOMAIN_STR, "Invalid domain string"},
1032498b56bSopenharmony_ci    {ERR_LOG_PERSIST_FILE_SIZE_INVALID, "Invalid log persist file size, file size should be in range ["
1042498b56bSopenharmony_ci    + Size2Str(MIN_LOG_FILE_SIZE) + ", " + Size2Str(MAX_LOG_FILE_SIZE) + "]"},
1052498b56bSopenharmony_ci    {ERR_LOG_PERSIST_FILE_NAME_INVALID, "Invalid log persist file name, file name should not contain [\\/:*?\"<>|]"},
1062498b56bSopenharmony_ci    {ERR_LOG_PERSIST_COMPRESS_BUFFER_EXP, "Invalid Log persist compression buffer"},
1072498b56bSopenharmony_ci    {ERR_LOG_PERSIST_FILE_PATH_INVALID, "Invalid persister file path or persister directory does not exist"},
1082498b56bSopenharmony_ci    {ERR_LOG_PERSIST_COMPRESS_INIT_FAIL, "Log persist compression initialization failed"},
1092498b56bSopenharmony_ci    {ERR_LOG_PERSIST_FILE_OPEN_FAIL, "Log persist open file failed"},
1102498b56bSopenharmony_ci    {ERR_LOG_PERSIST_JOBID_FAIL, "Log persist jobid not exist"},
1112498b56bSopenharmony_ci    {ERR_LOG_PERSIST_TASK_EXISTED, "Log persist task is existed"},
1122498b56bSopenharmony_ci    {ERR_DOMAIN_INVALID, ("Invalid domain, domain should be in range (" + Uint2HexStr(DOMAIN_MIN)
1132498b56bSopenharmony_ci    + ", " +Uint2HexStr(DOMAIN_MAX) +"]")},
1142498b56bSopenharmony_ci    {ERR_MSG_LEN_INVALID, "Invalid message length"},
1152498b56bSopenharmony_ci    {ERR_LOG_PERSIST_JOBID_INVALID, "Invalid jobid, jobid should be in range [" + to_string(JOB_ID_MIN)
1162498b56bSopenharmony_ci    + ", " + to_string(JOB_ID_MAX) + ")"},
1172498b56bSopenharmony_ci    {ERR_BUFF_SIZE_INVALID, ("Invalid buffer size, buffer size should be in range [" + Size2Str(MIN_BUFFER_SIZE)
1182498b56bSopenharmony_ci    + ", " + Size2Str(MAX_BUFFER_SIZE) + "]")},
1192498b56bSopenharmony_ci    {ERR_COMMAND_INVALID, "Mutlti commands can't be used in combination"},
1202498b56bSopenharmony_ci    {ERR_LOG_FILE_NUM_INVALID, "Invalid number of files"},
1212498b56bSopenharmony_ci    {ERR_NOT_NUMBER_STR, "Not a numeric string"},
1222498b56bSopenharmony_ci    {ERR_TOO_MANY_ARGUMENTS, "Too many arguments"},
1232498b56bSopenharmony_ci    {ERR_DUPLICATE_OPTION, "Too many duplicate options"},
1242498b56bSopenharmony_ci    {ERR_INVALID_ARGUMENT, "Invalid argument"},
1252498b56bSopenharmony_ci    {ERR_TOO_MANY_DOMAINS, "Max domain count is " + to_string(MAX_DOMAINS)},
1262498b56bSopenharmony_ci    {ERR_INVALID_SIZE_STR, "Invalid size string"},
1272498b56bSopenharmony_ci    {ERR_TOO_MANY_PIDS, "Max pid count is " + to_string(MAX_PIDS)},
1282498b56bSopenharmony_ci    {ERR_TOO_MANY_TAGS, "Max tag count is " + to_string(MAX_TAGS)},
1292498b56bSopenharmony_ci    {ERR_TAG_STR_TOO_LONG, ("Tag string too long, max length is " + to_string(MAX_TAG_LEN - 1))},
1302498b56bSopenharmony_ci    {ERR_REGEX_STR_TOO_LONG, ("Regular expression too long, max length is " + to_string(MAX_REGEX_STR_LEN - 1))},
1312498b56bSopenharmony_ci    {ERR_FILE_NAME_TOO_LONG, ("File name too long, max length is " + to_string(MAX_FILE_NAME_LEN))},
1322498b56bSopenharmony_ci    {ERR_SOCKET_CLIENT_INIT_FAIL, "Socket client init failed"},
1332498b56bSopenharmony_ci    {ERR_SOCKET_WRITE_MSG_HEADER_FAIL, "Socket rite message header failed"},
1342498b56bSopenharmony_ci    {ERR_SOCKET_WRITE_CMD_FAIL, "Socket write command failed"},
1352498b56bSopenharmony_ci    {ERR_SOCKET_RECEIVE_RSP, "Unable to receive message from socket"},
1362498b56bSopenharmony_ci    {ERR_PERSIST_TASK_EMPTY, "No running persist task, please check"},
1372498b56bSopenharmony_ci    {ERR_JOBID_NOT_EXSIST, "Persist task of this job id doesn't exist, please check"},
1382498b56bSopenharmony_ci    {ERR_TOO_MANY_JOBS, ("Too many jobs are running, max job count is:" + to_string(MAX_JOBS))},
1392498b56bSopenharmony_ci    {ERR_STATS_NOT_ENABLE, "Statistic feature is not enable, "
1402498b56bSopenharmony_ci     "please set param persist.sys.hilog.stats true to enable it, "
1412498b56bSopenharmony_ci     "further more, you can set persist.sys.hilog.stats.tag true to enable counting log by tags"},
1422498b56bSopenharmony_ci    {ERR_NO_RUNNING_TASK, "No running persistent task"},
1432498b56bSopenharmony_ci    {ERR_NO_PID_PERMISSION, "Permission denied, only shell and root can filter logs by pid"},
1442498b56bSopenharmony_ci}, RET_FAIL, "Unknown error code");
1452498b56bSopenharmony_ci
1462498b56bSopenharmony_cistring ErrorCode2Str(int16_t errorCode)
1472498b56bSopenharmony_ci{
1482498b56bSopenharmony_ci    return g_ErrorMsgs.GetValue((uint16_t)errorCode) + " [CODE: " + to_string(errorCode) + "]";
1492498b56bSopenharmony_ci}
1502498b56bSopenharmony_ci
1512498b56bSopenharmony_ci// Log Types&Strings Map
1522498b56bSopenharmony_cistatic const StringMap g_LogTypes({
1532498b56bSopenharmony_ci        {LOG_INIT, "init"}, {LOG_CORE, "core"}, {LOG_APP, "app"}, {LOG_KMSG, "kmsg"},
1542498b56bSopenharmony_ci        {LOG_ONLY_PRERELEASE, "only_prerelease"}
1552498b56bSopenharmony_ci}, LOG_TYPE_MAX, "invalid");
1562498b56bSopenharmony_ci
1572498b56bSopenharmony_cistring LogType2Str(uint16_t logType)
1582498b56bSopenharmony_ci{
1592498b56bSopenharmony_ci    return g_LogTypes.GetValue(logType);
1602498b56bSopenharmony_ci}
1612498b56bSopenharmony_ci
1622498b56bSopenharmony_ciuint16_t Str2LogType(const string& str)
1632498b56bSopenharmony_ci{
1642498b56bSopenharmony_ci    return g_LogTypes.GetKey(str);
1652498b56bSopenharmony_ci}
1662498b56bSopenharmony_ci
1672498b56bSopenharmony_cistring ComboLogType2Str(uint16_t shiftType)
1682498b56bSopenharmony_ci{
1692498b56bSopenharmony_ci    vector<uint16_t> types = g_LogTypes.GetAllKeys();
1702498b56bSopenharmony_ci    string str = "";
1712498b56bSopenharmony_ci    uint16_t typeAll = 0;
1722498b56bSopenharmony_ci
1732498b56bSopenharmony_ci    for (uint16_t t : types) {
1742498b56bSopenharmony_ci        typeAll |= (1 << t);
1752498b56bSopenharmony_ci    }
1762498b56bSopenharmony_ci    shiftType &= typeAll;
1772498b56bSopenharmony_ci    for (uint16_t t: types) {
1782498b56bSopenharmony_ci        if ((1 << t) & shiftType) {
1792498b56bSopenharmony_ci            shiftType &= (~(1 << t));
1802498b56bSopenharmony_ci            str += (LogType2Str(t) + (shiftType != 0 ? "," : ""));
1812498b56bSopenharmony_ci        }
1822498b56bSopenharmony_ci        if (shiftType == 0) {
1832498b56bSopenharmony_ci            break;
1842498b56bSopenharmony_ci        }
1852498b56bSopenharmony_ci    }
1862498b56bSopenharmony_ci    return str;
1872498b56bSopenharmony_ci}
1882498b56bSopenharmony_ci
1892498b56bSopenharmony_ciuint16_t Str2ComboLogType(const string& str)
1902498b56bSopenharmony_ci{
1912498b56bSopenharmony_ci    uint16_t logTypes = 0;
1922498b56bSopenharmony_ci    if (str == "") {
1932498b56bSopenharmony_ci        logTypes = (1 << LOG_CORE) | (1 << LOG_APP) | (1 << LOG_ONLY_PRERELEASE);
1942498b56bSopenharmony_ci        return logTypes;
1952498b56bSopenharmony_ci    }
1962498b56bSopenharmony_ci    vector<string> vec;
1972498b56bSopenharmony_ci    Split(str, vec);
1982498b56bSopenharmony_ci    for (auto& it : vec) {
1992498b56bSopenharmony_ci        if (it == "") {
2002498b56bSopenharmony_ci            continue;
2012498b56bSopenharmony_ci        }
2022498b56bSopenharmony_ci        uint16_t t = Str2LogType(it);
2032498b56bSopenharmony_ci        if (t == LOG_TYPE_MAX) {
2042498b56bSopenharmony_ci            return 0;
2052498b56bSopenharmony_ci        }
2062498b56bSopenharmony_ci        logTypes |= (1 << t);
2072498b56bSopenharmony_ci    }
2082498b56bSopenharmony_ci    return logTypes;
2092498b56bSopenharmony_ci}
2102498b56bSopenharmony_ci
2112498b56bSopenharmony_civector<uint16_t> GetAllLogTypes()
2122498b56bSopenharmony_ci{
2132498b56bSopenharmony_ci    return g_LogTypes.GetAllKeys();
2142498b56bSopenharmony_ci}
2152498b56bSopenharmony_ci
2162498b56bSopenharmony_ci// Log Levels&Strings Map
2172498b56bSopenharmony_cistatic const StringMap g_LogLevels({
2182498b56bSopenharmony_ci    {LOG_DEBUG, "DEBUG"}, {LOG_INFO, "INFO"}, {LOG_WARN, "WARN"},
2192498b56bSopenharmony_ci    {LOG_ERROR, "ERROR"}, {LOG_FATAL, "FATAL"}, {LOG_LEVEL_MAX, "X"}
2202498b56bSopenharmony_ci}, LOG_LEVEL_MIN, "INVALID", [](const string& l1, const string& l2) {
2212498b56bSopenharmony_ci    if (l1.length() == l2.length()) {
2222498b56bSopenharmony_ci        return std::equal(l1.begin(), l1.end(), l2.begin(), [](char a, char b) {
2232498b56bSopenharmony_ci            return std::tolower(a) == std::tolower(b);
2242498b56bSopenharmony_ci        });
2252498b56bSopenharmony_ci    } else {
2262498b56bSopenharmony_ci        return false;
2272498b56bSopenharmony_ci    }
2282498b56bSopenharmony_ci});
2292498b56bSopenharmony_ci
2302498b56bSopenharmony_cistring LogLevel2Str(uint16_t logLevel)
2312498b56bSopenharmony_ci{
2322498b56bSopenharmony_ci    return g_LogLevels.GetValue(logLevel);
2332498b56bSopenharmony_ci}
2342498b56bSopenharmony_ci
2352498b56bSopenharmony_ciuint16_t Str2LogLevel(const string& str)
2362498b56bSopenharmony_ci{
2372498b56bSopenharmony_ci    return g_LogLevels.GetKey(str);
2382498b56bSopenharmony_ci}
2392498b56bSopenharmony_ci
2402498b56bSopenharmony_ci// Log Levels&Short Strings Map
2412498b56bSopenharmony_cistatic const StringMap g_ShortLogLevels({
2422498b56bSopenharmony_ci    {LOG_DEBUG, "D"}, {LOG_INFO, "I"}, {LOG_WARN, "W"},
2432498b56bSopenharmony_ci    {LOG_ERROR, "E"}, {LOG_FATAL, "F"}, {LOG_LEVEL_MAX, "X"}
2442498b56bSopenharmony_ci}, LOG_LEVEL_MIN, "V", [](const string& l1, const string& l2) {
2452498b56bSopenharmony_ci    return (l1.length() == 1 && std::tolower(l1[0]) == std::tolower(l2[0]));
2462498b56bSopenharmony_ci});
2472498b56bSopenharmony_ci
2482498b56bSopenharmony_cistring LogLevel2ShortStr(uint16_t logLevel)
2492498b56bSopenharmony_ci{
2502498b56bSopenharmony_ci    return g_ShortLogLevels.GetValue(logLevel);
2512498b56bSopenharmony_ci}
2522498b56bSopenharmony_ci
2532498b56bSopenharmony_ciuint16_t ShortStr2LogLevel(const string& str)
2542498b56bSopenharmony_ci{
2552498b56bSopenharmony_ci    return g_ShortLogLevels.GetKey(str);
2562498b56bSopenharmony_ci}
2572498b56bSopenharmony_ci
2582498b56bSopenharmony_ciuint16_t PrettyStr2LogLevel(const string& str)
2592498b56bSopenharmony_ci{
2602498b56bSopenharmony_ci    uint16_t level = ShortStr2LogLevel(str);
2612498b56bSopenharmony_ci    if (level == static_cast<uint16_t>(LOG_LEVEL_MIN)) {
2622498b56bSopenharmony_ci        return Str2LogLevel(str);
2632498b56bSopenharmony_ci    }
2642498b56bSopenharmony_ci    return level;
2652498b56bSopenharmony_ci}
2662498b56bSopenharmony_ci
2672498b56bSopenharmony_cistring ComboLogLevel2Str(uint16_t shiftLevel)
2682498b56bSopenharmony_ci{
2692498b56bSopenharmony_ci    vector<uint16_t> levels = g_ShortLogLevels.GetAllKeys();
2702498b56bSopenharmony_ci    string str = "";
2712498b56bSopenharmony_ci    uint16_t levelAll = 0;
2722498b56bSopenharmony_ci
2732498b56bSopenharmony_ci    for (uint16_t l : levels) {
2742498b56bSopenharmony_ci        levelAll |= (1 << l);
2752498b56bSopenharmony_ci    }
2762498b56bSopenharmony_ci    shiftLevel &= levelAll;
2772498b56bSopenharmony_ci    for (uint16_t l: levels) {
2782498b56bSopenharmony_ci        if ((1 << l) & shiftLevel) {
2792498b56bSopenharmony_ci            shiftLevel &= (~(1 << l));
2802498b56bSopenharmony_ci            str += (LogLevel2Str(l) + (shiftLevel != 0 ? "," : ""));
2812498b56bSopenharmony_ci        }
2822498b56bSopenharmony_ci        if (shiftLevel == 0) {
2832498b56bSopenharmony_ci            break;
2842498b56bSopenharmony_ci        }
2852498b56bSopenharmony_ci    }
2862498b56bSopenharmony_ci    return str;
2872498b56bSopenharmony_ci}
2882498b56bSopenharmony_ci
2892498b56bSopenharmony_ciuint16_t Str2ComboLogLevel(const string& str)
2902498b56bSopenharmony_ci{
2912498b56bSopenharmony_ci    uint16_t logLevels = 0;
2922498b56bSopenharmony_ci    if (str == "") {
2932498b56bSopenharmony_ci        logLevels = 0xFFFF;
2942498b56bSopenharmony_ci        return logLevels;
2952498b56bSopenharmony_ci    }
2962498b56bSopenharmony_ci    vector<string> vec;
2972498b56bSopenharmony_ci    Split(str, vec);
2982498b56bSopenharmony_ci    for (auto& it : vec) {
2992498b56bSopenharmony_ci        if (it == "") {
3002498b56bSopenharmony_ci            continue;
3012498b56bSopenharmony_ci        }
3022498b56bSopenharmony_ci        uint16_t t = PrettyStr2LogLevel(it);
3032498b56bSopenharmony_ci        if (t == LOG_LEVEL_MIN || t >= LOG_LEVEL_MAX) {
3042498b56bSopenharmony_ci            return 0;
3052498b56bSopenharmony_ci        }
3062498b56bSopenharmony_ci        logLevels |= (1 << t);
3072498b56bSopenharmony_ci    }
3082498b56bSopenharmony_ci    return logLevels;
3092498b56bSopenharmony_ci}
3102498b56bSopenharmony_ci
3112498b56bSopenharmony_civoid Split(const std::string& src, std::vector<std::string>& dest, const std::string& separator)
3122498b56bSopenharmony_ci{
3132498b56bSopenharmony_ci    std::string str = src;
3142498b56bSopenharmony_ci    std::string substring;
3152498b56bSopenharmony_ci    std::string::size_type start = 0;
3162498b56bSopenharmony_ci    std::string::size_type index;
3172498b56bSopenharmony_ci    dest.clear();
3182498b56bSopenharmony_ci    index = str.find_first_of(separator, start);
3192498b56bSopenharmony_ci    if (index == std::string::npos) {
3202498b56bSopenharmony_ci        dest.emplace_back(str);
3212498b56bSopenharmony_ci        return;
3222498b56bSopenharmony_ci    }
3232498b56bSopenharmony_ci    do {
3242498b56bSopenharmony_ci        substring = str.substr(start, index - start);
3252498b56bSopenharmony_ci        dest.emplace_back(substring);
3262498b56bSopenharmony_ci        start = index + separator.size();
3272498b56bSopenharmony_ci        index = str.find(separator, start);
3282498b56bSopenharmony_ci    } while (index != std::string::npos);
3292498b56bSopenharmony_ci    substring = str.substr(start);
3302498b56bSopenharmony_ci    if (substring != "") {
3312498b56bSopenharmony_ci        dest.emplace_back(substring);
3322498b56bSopenharmony_ci    }
3332498b56bSopenharmony_ci}
3342498b56bSopenharmony_ci
3352498b56bSopenharmony_ciuint32_t GetBitsCount(uint64_t n)
3362498b56bSopenharmony_ci{
3372498b56bSopenharmony_ci    uint32_t count = 0;
3382498b56bSopenharmony_ci    while (n != 0) {
3392498b56bSopenharmony_ci        ++count;
3402498b56bSopenharmony_ci        n = n & (n-1);
3412498b56bSopenharmony_ci    }
3422498b56bSopenharmony_ci    return count;
3432498b56bSopenharmony_ci}
3442498b56bSopenharmony_ci
3452498b56bSopenharmony_ciuint16_t GetBitPos(uint64_t n)
3462498b56bSopenharmony_ci{
3472498b56bSopenharmony_ci    if (!(n && (!(n & (n-1))))) { // only accpet the number which is power of 2
3482498b56bSopenharmony_ci        return 0;
3492498b56bSopenharmony_ci    }
3502498b56bSopenharmony_ci
3512498b56bSopenharmony_ci    uint16_t i = 0;
3522498b56bSopenharmony_ci    while (n >> (i++)) {}
3532498b56bSopenharmony_ci    i--;
3542498b56bSopenharmony_ci    return i-1;
3552498b56bSopenharmony_ci}
3562498b56bSopenharmony_ci
3572498b56bSopenharmony_cienum class Radix {
3582498b56bSopenharmony_ci    RADIX_DEC,
3592498b56bSopenharmony_ci    RADIX_HEX,
3602498b56bSopenharmony_ci};
3612498b56bSopenharmony_citemplate<typename T>
3622498b56bSopenharmony_cistatic string Num2Str(T num, Radix radix)
3632498b56bSopenharmony_ci{
3642498b56bSopenharmony_ci    stringstream ss;
3652498b56bSopenharmony_ci    auto r = std::dec;
3662498b56bSopenharmony_ci    if (radix == Radix::RADIX_HEX) {
3672498b56bSopenharmony_ci        r = std::hex;
3682498b56bSopenharmony_ci    }
3692498b56bSopenharmony_ci    ss << r << num;
3702498b56bSopenharmony_ci    return ss.str();
3712498b56bSopenharmony_ci}
3722498b56bSopenharmony_ci
3732498b56bSopenharmony_citemplate<typename T>
3742498b56bSopenharmony_cistatic void Str2Num(const string& str, T& num, Radix radix)
3752498b56bSopenharmony_ci{
3762498b56bSopenharmony_ci    T  i = 0;
3772498b56bSopenharmony_ci    std::stringstream ss;
3782498b56bSopenharmony_ci    auto r = std::dec;
3792498b56bSopenharmony_ci    if (radix == Radix::RADIX_HEX) {
3802498b56bSopenharmony_ci        r = std::hex;
3812498b56bSopenharmony_ci    }
3822498b56bSopenharmony_ci    ss << r << str;
3832498b56bSopenharmony_ci    ss >> i;
3842498b56bSopenharmony_ci    num = i;
3852498b56bSopenharmony_ci    return;
3862498b56bSopenharmony_ci}
3872498b56bSopenharmony_ci
3882498b56bSopenharmony_cistring Uint2DecStr(uint32_t i)
3892498b56bSopenharmony_ci{
3902498b56bSopenharmony_ci    return Num2Str(i, Radix::RADIX_DEC);
3912498b56bSopenharmony_ci}
3922498b56bSopenharmony_ci
3932498b56bSopenharmony_ciuint32_t DecStr2Uint(const string& str)
3942498b56bSopenharmony_ci{
3952498b56bSopenharmony_ci    uint32_t i = 0;
3962498b56bSopenharmony_ci    Str2Num(str, i, Radix::RADIX_DEC);
3972498b56bSopenharmony_ci    return i;
3982498b56bSopenharmony_ci}
3992498b56bSopenharmony_ci
4002498b56bSopenharmony_cistring Uint2HexStr(uint32_t i)
4012498b56bSopenharmony_ci{
4022498b56bSopenharmony_ci    return Num2Str(i, Radix::RADIX_HEX);
4032498b56bSopenharmony_ci}
4042498b56bSopenharmony_ci
4052498b56bSopenharmony_ciuint32_t HexStr2Uint(const string& str)
4062498b56bSopenharmony_ci{
4072498b56bSopenharmony_ci    uint32_t i = 0;
4082498b56bSopenharmony_ci    Str2Num(str, i, Radix::RADIX_HEX);
4092498b56bSopenharmony_ci    return i;
4102498b56bSopenharmony_ci}
4112498b56bSopenharmony_ci
4122498b56bSopenharmony_ci#if !defined(__WINDOWS__) and !defined(__LINUX__)
4132498b56bSopenharmony_cistring GetProgName()
4142498b56bSopenharmony_ci{
4152498b56bSopenharmony_ci#ifdef HILOG_USE_MUSL
4162498b56bSopenharmony_ci    return program_invocation_short_name;
4172498b56bSopenharmony_ci#else
4182498b56bSopenharmony_ci    return getprogname();
4192498b56bSopenharmony_ci#endif
4202498b56bSopenharmony_ci}
4212498b56bSopenharmony_ci#endif
4222498b56bSopenharmony_ci
4232498b56bSopenharmony_cistring GetNameByPid(uint32_t pid)
4242498b56bSopenharmony_ci{
4252498b56bSopenharmony_ci    char path[CMDLINE_PATH_LEN] = { 0 };
4262498b56bSopenharmony_ci    if (snprintf_s(path, CMDLINE_PATH_LEN, CMDLINE_PATH_LEN - 1, "/proc/%d/cmdline", pid) <= 0) {
4272498b56bSopenharmony_ci        return "";
4282498b56bSopenharmony_ci    }
4292498b56bSopenharmony_ci    char cmdline[CMDLINE_LEN] = { 0 };
4302498b56bSopenharmony_ci    int i = 0;
4312498b56bSopenharmony_ci    FILE *fp = fopen(path, "r");
4322498b56bSopenharmony_ci    if (fp == nullptr) {
4332498b56bSopenharmony_ci        return "";
4342498b56bSopenharmony_ci    }
4352498b56bSopenharmony_ci    while (i < (CMDLINE_LEN - 1)) {
4362498b56bSopenharmony_ci        char c = static_cast<char>(fgetc(fp));
4372498b56bSopenharmony_ci        // 0. don't need args of cmdline
4382498b56bSopenharmony_ci        // 1. ignore unvisible character
4392498b56bSopenharmony_ci        if (!isgraph(c)) {
4402498b56bSopenharmony_ci            break;
4412498b56bSopenharmony_ci        }
4422498b56bSopenharmony_ci        cmdline[i] = c;
4432498b56bSopenharmony_ci        i++;
4442498b56bSopenharmony_ci    }
4452498b56bSopenharmony_ci    (void)fclose(fp);
4462498b56bSopenharmony_ci    return cmdline;
4472498b56bSopenharmony_ci}
4482498b56bSopenharmony_ci
4492498b56bSopenharmony_ciuint32_t GetPPidByPid(uint32_t pid)
4502498b56bSopenharmony_ci{
4512498b56bSopenharmony_ci    uint32_t ppid = 0;
4522498b56bSopenharmony_ci    char path[STATUS_PATH_LEN] = { 0 };
4532498b56bSopenharmony_ci    if (snprintf_s(path, STATUS_PATH_LEN, STATUS_PATH_LEN - 1, "/proc/%u/status", pid) <= 0) {
4542498b56bSopenharmony_ci        return ppid;
4552498b56bSopenharmony_ci    }
4562498b56bSopenharmony_ci    FILE *fp = fopen(path, "r");
4572498b56bSopenharmony_ci    if (fp == nullptr) {
4582498b56bSopenharmony_ci        return ppid;
4592498b56bSopenharmony_ci    }
4602498b56bSopenharmony_ci    char buf[STATUS_LEN] = { 0 };
4612498b56bSopenharmony_ci    size_t ret = fread(buf, sizeof(char), STATUS_LEN - 1, fp);
4622498b56bSopenharmony_ci    (void)fclose(fp);
4632498b56bSopenharmony_ci    if (ret <= 0) {
4642498b56bSopenharmony_ci        return ppid;
4652498b56bSopenharmony_ci    } else {
4662498b56bSopenharmony_ci        buf[ret++] = '\0';
4672498b56bSopenharmony_ci    }
4682498b56bSopenharmony_ci    char *ppidLoc = strstr(buf, "PPid:");
4692498b56bSopenharmony_ci    if ((ppidLoc == nullptr) || (sscanf_s(ppidLoc, "PPid:%d", &ppid) == -1)) {
4702498b56bSopenharmony_ci        return ppid;
4712498b56bSopenharmony_ci    }
4722498b56bSopenharmony_ci    std::string ppidName = GetNameByPid(ppid);
4732498b56bSopenharmony_ci    // ppid fork the sh to execute hilog, sh is not wanted ppid
4742498b56bSopenharmony_ci    if (std::find(std::begin(SH_NAMES), std::end(SH_NAMES), ppidName) != std::end(SH_NAMES)) {
4752498b56bSopenharmony_ci        return GetPPidByPid(ppid);
4762498b56bSopenharmony_ci    }
4772498b56bSopenharmony_ci    return ppid;
4782498b56bSopenharmony_ci}
4792498b56bSopenharmony_ci
4802498b56bSopenharmony_ciuint64_t GenerateHash(const char *p, size_t size)
4812498b56bSopenharmony_ci{
4822498b56bSopenharmony_ci    static const uint64_t PRIME = 0x100000001B3ULL;
4832498b56bSopenharmony_ci    static const uint64_t BASIS = 0xCBF29CE484222325ULL;
4842498b56bSopenharmony_ci    uint64_t ret {BASIS};
4852498b56bSopenharmony_ci    unsigned long i = 0;
4862498b56bSopenharmony_ci    while (i < size) {
4872498b56bSopenharmony_ci        ret ^= *(p + i);
4882498b56bSopenharmony_ci        ret *= PRIME;
4892498b56bSopenharmony_ci        i++;
4902498b56bSopenharmony_ci    }
4912498b56bSopenharmony_ci    return ret;
4922498b56bSopenharmony_ci}
4932498b56bSopenharmony_ci
4942498b56bSopenharmony_civoid PrintErrorno(int err)
4952498b56bSopenharmony_ci{
4962498b56bSopenharmony_ci    constexpr int bufSize = 256;
4972498b56bSopenharmony_ci    char buf[bufSize] = { 0 };
4982498b56bSopenharmony_ci#ifndef __WINDOWS__
4992498b56bSopenharmony_ci    (void)strerror_r(err, buf, bufSize);
5002498b56bSopenharmony_ci#else
5012498b56bSopenharmony_ci    (void)strerror_s(buf, bufSize, err);
5022498b56bSopenharmony_ci#endif
5032498b56bSopenharmony_ci    std::cerr << "Errno: " << err << ", " << buf << std::endl;
5042498b56bSopenharmony_ci}
5052498b56bSopenharmony_ci
5062498b56bSopenharmony_ciint WaitingToDo(int max, const string& path, function<int(const string &path)> func)
5072498b56bSopenharmony_ci{
5082498b56bSopenharmony_ci    chrono::steady_clock::time_point start = chrono::steady_clock::now();
5092498b56bSopenharmony_ci    chrono::milliseconds wait(max);
5102498b56bSopenharmony_ci    while (true) {
5112498b56bSopenharmony_ci        if (func(path) != RET_FAIL) {
5122498b56bSopenharmony_ci            cout << "waiting for " << path << " successfully!" << endl;
5132498b56bSopenharmony_ci            return RET_SUCCESS;
5142498b56bSopenharmony_ci        }
5152498b56bSopenharmony_ci
5162498b56bSopenharmony_ci        std::this_thread::sleep_for(10ms);
5172498b56bSopenharmony_ci        if ((chrono::steady_clock::now() - start) > wait) {
5182498b56bSopenharmony_ci            cerr << "waiting for " << path << " failed!" << endl;
5192498b56bSopenharmony_ci            return RET_FAIL;
5202498b56bSopenharmony_ci        }
5212498b56bSopenharmony_ci    }
5222498b56bSopenharmony_ci}
5232498b56bSopenharmony_ci
5242498b56bSopenharmony_cistd::wstring StringToWstring(const std::string& input)
5252498b56bSopenharmony_ci{
5262498b56bSopenharmony_ci    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
5272498b56bSopenharmony_ci    return converter.from_bytes(input);
5282498b56bSopenharmony_ci}
5292498b56bSopenharmony_ci} // namespace HiviewDFX
5302498b56bSopenharmony_ci} // namespace OHOS
531