12498b56bSopenharmony_ci/* 22498b56bSopenharmony_ci * Copyright (c) 2021 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 <cstdlib> 162498b56bSopenharmony_ci#include <getopt.h> 172498b56bSopenharmony_ci#include <iostream> 182498b56bSopenharmony_ci#include <iomanip> 192498b56bSopenharmony_ci#include <ctime> 202498b56bSopenharmony_ci#include <functional> 212498b56bSopenharmony_ci#include <string_ex.h> 222498b56bSopenharmony_ci#include <securec.h> 232498b56bSopenharmony_ci#include <list> 242498b56bSopenharmony_ci 252498b56bSopenharmony_ci#include <hilog/log.h> 262498b56bSopenharmony_ci#include <hilog_common.h> 272498b56bSopenharmony_ci#include <log_utils.h> 282498b56bSopenharmony_ci#include <log_ioctl.h> 292498b56bSopenharmony_ci#include <log_print.h> 302498b56bSopenharmony_ci#include <properties.h> 312498b56bSopenharmony_ci 322498b56bSopenharmony_ci#include "log_display.h" 332498b56bSopenharmony_ci 342498b56bSopenharmony_cinamespace OHOS { 352498b56bSopenharmony_cinamespace HiviewDFX { 362498b56bSopenharmony_ciusing namespace std; 372498b56bSopenharmony_cistatic void FormatHelper() 382498b56bSopenharmony_ci{ 392498b56bSopenharmony_ci cout 402498b56bSopenharmony_ci << " -v <format>, --format=<format>" << endl 412498b56bSopenharmony_ci << " Show logs in different formats, options are:" << endl 422498b56bSopenharmony_ci << " color or colour display colorful logs by log level.i.e." << endl 432498b56bSopenharmony_ci << " \x1B[38;5;75mDEBUG \x1B[38;5;40mINFO \x1B[38;5;166mWARN" 442498b56bSopenharmony_ci << " \x1B[38;5;196mERROR \x1B[38;5;226mFATAL\x1B[0m" << endl 452498b56bSopenharmony_ci << " time format options are(single accepted):" << endl 462498b56bSopenharmony_ci << " time display local time, this is default." << endl 472498b56bSopenharmony_ci << " epoch display the time from 1970/1/1." << endl 482498b56bSopenharmony_ci << " monotonic display the cpu time from bootup." << endl 492498b56bSopenharmony_ci << " time accuracy format options are(single accepted):" << endl 502498b56bSopenharmony_ci << " msec display time by millisecond, this is default." << endl 512498b56bSopenharmony_ci << " usec display time by microsecond." << endl 522498b56bSopenharmony_ci << " nsec display time by nanosecond." << endl 532498b56bSopenharmony_ci << " year display the year when -v time is specified." << endl 542498b56bSopenharmony_ci << " zone display the time zone when -v time is specified." << endl 552498b56bSopenharmony_ci << " wrap display the log without prefix when a log line is wrapped." << endl 562498b56bSopenharmony_ci << " Different types of formats can be combined, such as:" << endl 572498b56bSopenharmony_ci << " -v color -v time -v msec -v year -v zone." << endl; 582498b56bSopenharmony_ci} 592498b56bSopenharmony_ci 602498b56bSopenharmony_cistatic void QueryHelper() 612498b56bSopenharmony_ci{ 622498b56bSopenharmony_ci cout 632498b56bSopenharmony_ci << "Querying logs options:" << endl 642498b56bSopenharmony_ci << " No option performs a blocking read and keeps printing." << endl 652498b56bSopenharmony_ci << " -x --exit" << endl 662498b56bSopenharmony_ci << " Performs a non-blocking read and exits when all logs in buffer are printed." << endl 672498b56bSopenharmony_ci << " -a <n>, --head=<n>" << endl 682498b56bSopenharmony_ci << " Show n lines logs on head of buffer." << endl 692498b56bSopenharmony_ci << " -z <n>, --tail=<n>" << endl 702498b56bSopenharmony_ci << " Show n lines logs on tail of buffer." << endl 712498b56bSopenharmony_ci << " -t <type>, --type=<type>" << endl 722498b56bSopenharmony_ci << " Show specific type/types logs with format: type1,type2,type3" << endl 732498b56bSopenharmony_ci << " Don't show specific type/types logs with format: ^type1,type2,type3" << endl 742498b56bSopenharmony_ci << " Type coule be: app/core/init/kmsg/only_prerelease, kmsg can't combine with others." << endl 752498b56bSopenharmony_ci << " Default types are: app,core,init,only_prerelease." << endl 762498b56bSopenharmony_ci << " -L <level>, --level=<level>" << endl 772498b56bSopenharmony_ci << " Show specific level/levels logs with format: level1,level2,level3" << endl 782498b56bSopenharmony_ci << " Don't show specific level/levels logs with format: ^level1,level2,level3" << endl 792498b56bSopenharmony_ci << " Long and short level string are both accepted" << endl 802498b56bSopenharmony_ci << " Long level string coule be: DEBUG/INFO/WARN/ERROR/FATAL." << endl 812498b56bSopenharmony_ci << " Short level string coule be: D/I/W/E/F." << endl 822498b56bSopenharmony_ci << " Default levels are all levels." << endl 832498b56bSopenharmony_ci << " -D <domain>, --domain=<domain>" << endl 842498b56bSopenharmony_ci << " Show specific domain/domains logs with format: domain1,domain2,doman3" << endl 852498b56bSopenharmony_ci << " Don't show specific domain/domains logs with format: ^domain1,domain2,doman3" << endl 862498b56bSopenharmony_ci << " Max domain count is " << MAX_DOMAINS << "." << endl 872498b56bSopenharmony_ci << " See domain description at the end of this message." << endl 882498b56bSopenharmony_ci << " -T <tag>, --tag=<tag>" << endl 892498b56bSopenharmony_ci << " Show specific tag/tags logs with format: tag1,tag2,tag3" << endl 902498b56bSopenharmony_ci << " Don't show specific tag/tags logs with format: ^tag1,tag2,tag3" << endl 912498b56bSopenharmony_ci << " Max tag count is " << MAX_TAGS << "." << endl 922498b56bSopenharmony_ci << " -P <pid>, --pid=<pid>" << endl 932498b56bSopenharmony_ci << " Show specific pid/pids logs with format: pid1,pid2,pid3" << endl 942498b56bSopenharmony_ci << " Don't show specific domain/domains logs with format: ^pid1,pid2,pid3" << endl 952498b56bSopenharmony_ci << " Max pid count is " << MAX_PIDS << "." << endl 962498b56bSopenharmony_ci << " -e <expr>, --regex=<expr>" << endl 972498b56bSopenharmony_ci << " Show the logs which match the regular expression <expr>." << endl; 982498b56bSopenharmony_ci FormatHelper(); 992498b56bSopenharmony_ci} 1002498b56bSopenharmony_ci 1012498b56bSopenharmony_cistatic void ClearHelper() 1022498b56bSopenharmony_ci{ 1032498b56bSopenharmony_ci cout 1042498b56bSopenharmony_ci << "-r" << endl 1052498b56bSopenharmony_ci << " Remove all logs in hilogd buffer, advanced option:" << endl 1062498b56bSopenharmony_ci << " -t <type>, --type=<type>" << endl 1072498b56bSopenharmony_ci << " Remove specific type/types logs in buffer with format: type1,type2,type3" << endl 1082498b56bSopenharmony_ci << " Type coule be: app/core/init/kmsg/only_prerelease." << endl 1092498b56bSopenharmony_ci << " Default types are: app,core,only_prerelease" << endl; 1102498b56bSopenharmony_ci} 1112498b56bSopenharmony_ci 1122498b56bSopenharmony_cistatic void BufferHelper() 1132498b56bSopenharmony_ci{ 1142498b56bSopenharmony_ci cout 1152498b56bSopenharmony_ci << "-g" << endl 1162498b56bSopenharmony_ci << " Query hilogd buffer size, advanced option:" << endl 1172498b56bSopenharmony_ci << " -t <type>, --type=<type>" << endl 1182498b56bSopenharmony_ci << " Query specific type/types buffer size with format: type1,type2,type3" << endl 1192498b56bSopenharmony_ci << " Type coule be: app/core/init/kmsg/only_prerelease." << endl 1202498b56bSopenharmony_ci << " Default types are: app,core,only_prerelease" << endl 1212498b56bSopenharmony_ci << "-G <size>, --buffer-size=<size>" << endl 1222498b56bSopenharmony_ci << " Set hilogd buffer size, <size> could be number or number with unit." << endl 1232498b56bSopenharmony_ci << " Unit could be: B/K/M/G which represents Byte/Kilobyte/Megabyte/Gigabyte." << endl 1242498b56bSopenharmony_ci << " <size> range: [" << Size2Str(MIN_BUFFER_SIZE) << "," << Size2Str(MAX_BUFFER_SIZE) << "]." << endl 1252498b56bSopenharmony_ci << " Advanced option:" << endl 1262498b56bSopenharmony_ci << " -t <type>, --type=<type>" << endl 1272498b56bSopenharmony_ci << " Set specific type/types log buffer size with format: type1,type2,type3" << endl 1282498b56bSopenharmony_ci << " Type coule be: app/core/init/kmsg/only_prerelease." << endl 1292498b56bSopenharmony_ci << " Default types are: app,core,only_prerelease" << endl 1302498b56bSopenharmony_ci << " **It's a persistant configuration**" << endl; 1312498b56bSopenharmony_ci} 1322498b56bSopenharmony_ci 1332498b56bSopenharmony_cistatic void StatisticHelper() 1342498b56bSopenharmony_ci{ 1352498b56bSopenharmony_ci cout 1362498b56bSopenharmony_ci << "-s, --statistics" << endl 1372498b56bSopenharmony_ci << " Query log statistic information." << endl 1382498b56bSopenharmony_ci << " Set param persist.sys.hilog.stats true to enable statistic." << endl 1392498b56bSopenharmony_ci << " Set param persist.sys.hilog.stats.tag true to enable statistic of log tag." << endl 1402498b56bSopenharmony_ci << "-S" << endl 1412498b56bSopenharmony_ci << " Clear hilogd statistic information." << endl; 1422498b56bSopenharmony_ci} 1432498b56bSopenharmony_ci 1442498b56bSopenharmony_cistatic void PersistTaskHelper() 1452498b56bSopenharmony_ci{ 1462498b56bSopenharmony_ci cout 1472498b56bSopenharmony_ci << "-w <control>,--write=<control>" << endl 1482498b56bSopenharmony_ci << " Log persistance task control, options are:" << endl 1492498b56bSopenharmony_ci << " query query tasks informations" << endl 1502498b56bSopenharmony_ci << " stop stop all tasks" << endl 1512498b56bSopenharmony_ci << " start start one task" << endl 1522498b56bSopenharmony_ci << " refresh refresh buffer content to file" << endl 1532498b56bSopenharmony_ci << " clear clear /data/log/hilog/hilog*.gz" << endl 1542498b56bSopenharmony_ci << " Persistance task is used for saving logs in files." << endl 1552498b56bSopenharmony_ci << " The files are saved in directory: " << HILOG_FILE_DIR << endl 1562498b56bSopenharmony_ci << " Advanced options:" << endl 1572498b56bSopenharmony_ci << " -f <filename>, --filename=<filename>" << endl 1582498b56bSopenharmony_ci << " Set log file name, name should be valid of Linux FS." << endl 1592498b56bSopenharmony_ci << " -l <length>, --length=<length>" << endl 1602498b56bSopenharmony_ci << " Set single log file size. <length> could be number or number with unit." << endl 1612498b56bSopenharmony_ci << " Unit could be: B/K/M/G which represents Byte/Kilobyte/Megabyte/Gigabyte." << endl 1622498b56bSopenharmony_ci << " <length> range: [" << Size2Str(MIN_LOG_FILE_SIZE) <<", " << Size2Str(MAX_LOG_FILE_SIZE) << "]." << endl 1632498b56bSopenharmony_ci << " -n <number>, --number<number>" << endl 1642498b56bSopenharmony_ci << " Set max log file numbers, log file rotate when files count over this number." << endl 1652498b56bSopenharmony_ci << " <number> range: [" << MIN_LOG_FILE_NUM << ", " << MAX_LOG_FILE_NUM << "]." << endl 1662498b56bSopenharmony_ci << " -m <compress algorithm>,--stream=<compress algorithm>" << endl 1672498b56bSopenharmony_ci << " Set log file compressed algorithm, options are:" << endl 1682498b56bSopenharmony_ci << " none write file with non-compressed logs." << endl 1692498b56bSopenharmony_ci << " zlib write file with zlib compressed logs." << endl 1702498b56bSopenharmony_ci << " -j <jobid>, --jobid<jobid>" << endl 1712498b56bSopenharmony_ci << " Start/stop specific task of <jobid>." << endl 1722498b56bSopenharmony_ci << " <jobid> range: [" << JOB_ID_MIN << ", 0x" << hex << JOB_ID_MAX << dec << ")." << endl 1732498b56bSopenharmony_ci << " User can start task with options (t/L/D/T/P/e/v) as if using them when \"Query logs\" too." << endl 1742498b56bSopenharmony_ci << " **It's a persistant configuration**" << endl; 1752498b56bSopenharmony_ci} 1762498b56bSopenharmony_ci 1772498b56bSopenharmony_cistatic void PrivateHelper() 1782498b56bSopenharmony_ci{ 1792498b56bSopenharmony_ci cout 1802498b56bSopenharmony_ci << "-p <on/off>, --privacy <on/off>" << endl 1812498b56bSopenharmony_ci << " Set HILOG api privacy formatter feature on or off." << endl 1822498b56bSopenharmony_ci << " **It's a temporary configuration, will be lost after reboot**" << endl; 1832498b56bSopenharmony_ci} 1842498b56bSopenharmony_ci 1852498b56bSopenharmony_cistatic void KmsgHelper() 1862498b56bSopenharmony_ci{ 1872498b56bSopenharmony_ci cout 1882498b56bSopenharmony_ci << "-k <on/off>, --kmsg <on/off>" << endl 1892498b56bSopenharmony_ci << " Set hilogd storing kmsg log feature on or off" << endl 1902498b56bSopenharmony_ci << " **It's a persistant configuration**" << endl; 1912498b56bSopenharmony_ci} 1922498b56bSopenharmony_ci 1932498b56bSopenharmony_cistatic void FlowControlHelper() 1942498b56bSopenharmony_ci{ 1952498b56bSopenharmony_ci cout 1962498b56bSopenharmony_ci << "-Q <control-type>" << endl 1972498b56bSopenharmony_ci << " Set log flow-control feature on or off, options are:" << endl 1982498b56bSopenharmony_ci << " pidon process flow control on" << endl 1992498b56bSopenharmony_ci << " pidoff process flow control off" << endl 2002498b56bSopenharmony_ci << " domainon domain flow control on" << endl 2012498b56bSopenharmony_ci << " domainoff domain flow control off" << endl 2022498b56bSopenharmony_ci << " **It's a temporary configuration, will be lost after reboot**" << endl; 2032498b56bSopenharmony_ci} 2042498b56bSopenharmony_ci 2052498b56bSopenharmony_cistatic void BaseLevelHelper() 2062498b56bSopenharmony_ci{ 2072498b56bSopenharmony_ci cout 2082498b56bSopenharmony_ci << "-b <loglevel>, --baselevel=<loglevel>" << endl 2092498b56bSopenharmony_ci << " Set global loggable level to <loglevel>" << endl 2102498b56bSopenharmony_ci << " Long and short level string are both accepted." << endl 2112498b56bSopenharmony_ci << " Long level string coule be: DEBUG/INFO/WARN/ERROR/FATAL/X." << endl 2122498b56bSopenharmony_ci << " Short level string coule be: D/I/W/E/F/X." << endl 2132498b56bSopenharmony_ci << " X means that loggable level is higher than the max level, no log could be printed." << endl 2142498b56bSopenharmony_ci << " Advanced options:" << endl 2152498b56bSopenharmony_ci << " -D <domain>, --domain=<domain>" << endl 2162498b56bSopenharmony_ci << " Set specific domain loggable level." << endl 2172498b56bSopenharmony_ci << " See domain description at the end of this message." << endl 2182498b56bSopenharmony_ci << " -T <tag>, --tag=<tag>" << endl 2192498b56bSopenharmony_ci << " Set specific tag loggable level." << endl 2202498b56bSopenharmony_ci << " The priority is: tag level > domain level > global level." << endl 2212498b56bSopenharmony_ci << " **It's a temporary configuration, will be lost after reboot**" << endl; 2222498b56bSopenharmony_ci} 2232498b56bSopenharmony_ci 2242498b56bSopenharmony_cistatic void DomainHelper() 2252498b56bSopenharmony_ci{ 2262498b56bSopenharmony_ci cout 2272498b56bSopenharmony_ci << endl << endl 2282498b56bSopenharmony_ci << "Domain description:" << endl 2292498b56bSopenharmony_ci << " Log type \"core\" & \"init\" & \"only_prerelease\" are used for OS subsystems, the range is" 2302498b56bSopenharmony_ci << " [0x" << hex << DOMAIN_OS_MIN << ", 0x" << DOMAIN_OS_MAX << "]" << endl 2312498b56bSopenharmony_ci << " Log type \"app\" is used for applications, the range is [0x" << DOMAIN_APP_MIN << "," 2322498b56bSopenharmony_ci << " 0x" << DOMAIN_APP_MAX << "]" << dec << endl 2332498b56bSopenharmony_ci << " To reduce redundant info when printing logs, only last five hex numbers of domain are printed" << endl 2342498b56bSopenharmony_ci << " So if user wants to use -D option to filter OS logs, user should add 0xD0 as prefix to the printed domain:" 2352498b56bSopenharmony_ci << endl 2362498b56bSopenharmony_ci << " Exapmle: hilog -D 0xD0xxxxx" << endl 2372498b56bSopenharmony_ci << " The xxxxx is the domain string printed in logs." << endl; 2382498b56bSopenharmony_ci} 2392498b56bSopenharmony_ci 2402498b56bSopenharmony_cistatic void ComboHelper() 2412498b56bSopenharmony_ci{ 2422498b56bSopenharmony_ci cout 2432498b56bSopenharmony_ci << "The first layer options can't be used in combination, ILLEGAL expamples:" << endl 2442498b56bSopenharmony_ci << " hilog -S -s; hilog -w start -r; hilog -p on -k on -b D" << endl; 2452498b56bSopenharmony_ci} 2462498b56bSopenharmony_ci 2472498b56bSopenharmony_ciusing HelperFunc = std::function<void()>; 2482498b56bSopenharmony_cistatic const std::list<pair<string, HelperFunc>> g_HelperList = { 2492498b56bSopenharmony_ci {"query", QueryHelper}, 2502498b56bSopenharmony_ci {"clear", ClearHelper}, 2512498b56bSopenharmony_ci {"buffer", BufferHelper}, 2522498b56bSopenharmony_ci {"stats", StatisticHelper}, 2532498b56bSopenharmony_ci {"persist", PersistTaskHelper}, 2542498b56bSopenharmony_ci {"private", PrivateHelper}, 2552498b56bSopenharmony_ci {"kmsg", KmsgHelper}, 2562498b56bSopenharmony_ci {"flowcontrol", FlowControlHelper}, 2572498b56bSopenharmony_ci {"baselevel", BaseLevelHelper}, 2582498b56bSopenharmony_ci {"combo", ComboHelper}, 2592498b56bSopenharmony_ci {"domain", DomainHelper}, 2602498b56bSopenharmony_ci}; 2612498b56bSopenharmony_ci 2622498b56bSopenharmony_cistatic void Helper(const string& arg) 2632498b56bSopenharmony_ci{ 2642498b56bSopenharmony_ci cout << "Usage:" << endl 2652498b56bSopenharmony_ci << "-h --help" << endl 2662498b56bSopenharmony_ci << " Show all help information." << endl 2672498b56bSopenharmony_ci << " Show single help information with option: " << endl 2682498b56bSopenharmony_ci << " query/clear/buffer/stats/persist/private/kmsg/flowcontrol/baselevel/domain/combo" << endl; 2692498b56bSopenharmony_ci for (auto &it : g_HelperList) { 2702498b56bSopenharmony_ci if (arg == "" || arg == it.first) { 2712498b56bSopenharmony_ci it.second(); 2722498b56bSopenharmony_ci } 2732498b56bSopenharmony_ci } 2742498b56bSopenharmony_ci return; 2752498b56bSopenharmony_ci} 2762498b56bSopenharmony_ci 2772498b56bSopenharmony_cistatic void PrintErr(int error) 2782498b56bSopenharmony_ci{ 2792498b56bSopenharmony_ci cerr << ErrorCode2Str(error) << endl; 2802498b56bSopenharmony_ci} 2812498b56bSopenharmony_ci 2822498b56bSopenharmony_cistatic void PrintResult(int ret, const string& msg) 2832498b56bSopenharmony_ci{ 2842498b56bSopenharmony_ci cout << msg << ((ret == RET_SUCCESS) ? " successfully" : " failed") << endl; 2852498b56bSopenharmony_ci} 2862498b56bSopenharmony_ci 2872498b56bSopenharmony_cienum class ControlCmd { 2882498b56bSopenharmony_ci NOT_CMD = -1, 2892498b56bSopenharmony_ci CMD_HELP = 0, 2902498b56bSopenharmony_ci CMD_QUERY, 2912498b56bSopenharmony_ci CMD_REMOVE, 2922498b56bSopenharmony_ci CMD_BUFFER_SIZE_QUERY, 2932498b56bSopenharmony_ci CMD_BUFFER_SIZE_SET, 2942498b56bSopenharmony_ci CMD_STATS_INFO_QUERY, 2952498b56bSopenharmony_ci CMD_STATS_INFO_CLEAR, 2962498b56bSopenharmony_ci CMD_PERSIST_TASK, 2972498b56bSopenharmony_ci CMD_PRIVATE_FEATURE_SET, 2982498b56bSopenharmony_ci CMD_KMSG_FEATURE_SET, 2992498b56bSopenharmony_ci CMD_FLOWCONTROL_FEATURE_SET, 3002498b56bSopenharmony_ci CMD_LOGLEVEL_SET, 3012498b56bSopenharmony_ci}; 3022498b56bSopenharmony_ci 3032498b56bSopenharmony_cistruct HilogArgs { 3042498b56bSopenharmony_ci uint16_t headLines; 3052498b56bSopenharmony_ci uint16_t baseLevel; 3062498b56bSopenharmony_ci bool blackDomain; 3072498b56bSopenharmony_ci int domainCount; 3082498b56bSopenharmony_ci uint32_t domains[MAX_DOMAINS]; 3092498b56bSopenharmony_ci string regex; 3102498b56bSopenharmony_ci string fileName; 3112498b56bSopenharmony_ci int32_t buffSize; 3122498b56bSopenharmony_ci uint32_t jobId; 3132498b56bSopenharmony_ci uint32_t fileSize; 3142498b56bSopenharmony_ci uint16_t levels; 3152498b56bSopenharmony_ci string stream; 3162498b56bSopenharmony_ci uint16_t fileNum; 3172498b56bSopenharmony_ci bool blackPid; 3182498b56bSopenharmony_ci int pidCount; 3192498b56bSopenharmony_ci uint32_t pids[MAX_PIDS]; 3202498b56bSopenharmony_ci uint16_t types; 3212498b56bSopenharmony_ci bool blackTag; 3222498b56bSopenharmony_ci int tagCount; 3232498b56bSopenharmony_ci string tags[MAX_TAGS]; 3242498b56bSopenharmony_ci bool colorful; 3252498b56bSopenharmony_ci FormatTime timeFormat; 3262498b56bSopenharmony_ci FormatTimeAccu timeAccuFormat; 3272498b56bSopenharmony_ci bool year; 3282498b56bSopenharmony_ci bool zone; 3292498b56bSopenharmony_ci bool wrap; 3302498b56bSopenharmony_ci bool noBlock; 3312498b56bSopenharmony_ci uint16_t tailLines; 3322498b56bSopenharmony_ci 3332498b56bSopenharmony_ci HilogArgs() : headLines (0), baseLevel(0), blackDomain(false), domainCount(0), domains { 0 }, regex(""), 3342498b56bSopenharmony_ci fileName(""), buffSize(0), jobId(0), fileSize(0), levels(0), stream(""), fileNum(0), blackPid(false), 3352498b56bSopenharmony_ci pidCount(0), pids { 0 }, types(0), blackTag(false), tagCount(0), tags { "" }, colorful(false), 3362498b56bSopenharmony_ci timeFormat(FormatTime::INVALID), timeAccuFormat(FormatTimeAccu::INVALID), year(false), zone(false), 3372498b56bSopenharmony_ci wrap(false), noBlock(false), tailLines(0) {} 3382498b56bSopenharmony_ci 3392498b56bSopenharmony_ci void ToOutputRqst(OutputRqst& rqst) 3402498b56bSopenharmony_ci { 3412498b56bSopenharmony_ci rqst.headLines = headLines; 3422498b56bSopenharmony_ci rqst.types = types; 3432498b56bSopenharmony_ci rqst.levels = levels; 3442498b56bSopenharmony_ci rqst.blackDomain = blackDomain; 3452498b56bSopenharmony_ci rqst.domainCount = static_cast<uint8_t>(domainCount); 3462498b56bSopenharmony_ci int i; 3472498b56bSopenharmony_ci for (i = 0; i < domainCount; i++) { 3482498b56bSopenharmony_ci rqst.domains[i] = domains[i]; 3492498b56bSopenharmony_ci } 3502498b56bSopenharmony_ci rqst.blackTag = blackTag; 3512498b56bSopenharmony_ci rqst.tagCount = tagCount; 3522498b56bSopenharmony_ci for (i = 0; i < tagCount; i++) { 3532498b56bSopenharmony_ci (void)strncpy_s(rqst.tags[i], MAX_TAG_LEN, tags[i].c_str(), tags[i].length()); 3542498b56bSopenharmony_ci } 3552498b56bSopenharmony_ci rqst.blackPid = blackPid; 3562498b56bSopenharmony_ci rqst.pidCount = pidCount; 3572498b56bSopenharmony_ci for (i = 0; i < pidCount; i++) { 3582498b56bSopenharmony_ci rqst.pids[i] = pids[i]; 3592498b56bSopenharmony_ci } 3602498b56bSopenharmony_ci (void)strncpy_s(rqst.regex, MAX_REGEX_STR_LEN, regex.c_str(), regex.length()); 3612498b56bSopenharmony_ci rqst.noBlock = noBlock; 3622498b56bSopenharmony_ci rqst.tailLines = tailLines; 3632498b56bSopenharmony_ci } 3642498b56bSopenharmony_ci 3652498b56bSopenharmony_ci void ToPersistStartRqst(PersistStartRqst& rqst) 3662498b56bSopenharmony_ci { 3672498b56bSopenharmony_ci ToOutputRqst(rqst.outputFilter); 3682498b56bSopenharmony_ci rqst.jobId = jobId; 3692498b56bSopenharmony_ci rqst.fileNum = fileNum; 3702498b56bSopenharmony_ci rqst.fileSize = fileSize; 3712498b56bSopenharmony_ci (void)strncpy_s(rqst.fileName, MAX_FILE_NAME_LEN, fileName.c_str(), fileName.length()); 3722498b56bSopenharmony_ci (void)strncpy_s(rqst.stream, MAX_STREAM_NAME_LEN, stream.c_str(), stream.length()); 3732498b56bSopenharmony_ci } 3742498b56bSopenharmony_ci 3752498b56bSopenharmony_ci void ToPersistStopRqst(PersistStopRqst& rqst) 3762498b56bSopenharmony_ci { 3772498b56bSopenharmony_ci rqst.jobId = jobId; 3782498b56bSopenharmony_ci } 3792498b56bSopenharmony_ci 3802498b56bSopenharmony_ci void ToBufferSizeSetRqst(BufferSizeSetRqst& rqst) 3812498b56bSopenharmony_ci { 3822498b56bSopenharmony_ci rqst.types = types; 3832498b56bSopenharmony_ci rqst.size = buffSize; 3842498b56bSopenharmony_ci } 3852498b56bSopenharmony_ci 3862498b56bSopenharmony_ci void ToBufferSizeGetRqst(BufferSizeGetRqst& rqst) 3872498b56bSopenharmony_ci { 3882498b56bSopenharmony_ci rqst.types = types; 3892498b56bSopenharmony_ci } 3902498b56bSopenharmony_ci 3912498b56bSopenharmony_ci void ToStatsQueryRqst(StatsQueryRqst& rqst) 3922498b56bSopenharmony_ci { 3932498b56bSopenharmony_ci rqst.types = types; 3942498b56bSopenharmony_ci rqst.domainCount = static_cast<uint8_t>(domainCount); 3952498b56bSopenharmony_ci int i; 3962498b56bSopenharmony_ci for (i = 0; i < domainCount; i++) { 3972498b56bSopenharmony_ci rqst.domains[i] = domains[i]; 3982498b56bSopenharmony_ci } 3992498b56bSopenharmony_ci } 4002498b56bSopenharmony_ci 4012498b56bSopenharmony_ci void ToLogRemoveRqst(LogRemoveRqst& rqst) 4022498b56bSopenharmony_ci { 4032498b56bSopenharmony_ci rqst.types = types; 4042498b56bSopenharmony_ci } 4052498b56bSopenharmony_ci}; 4062498b56bSopenharmony_ci 4072498b56bSopenharmony_ciusing OptHandler = std::function<int(HilogArgs& context, const char *arg)>; 4082498b56bSopenharmony_ci 4092498b56bSopenharmony_cistatic int QueryLogHandler(HilogArgs& context, const char *arg) 4102498b56bSopenharmony_ci{ 4112498b56bSopenharmony_ci OutputRqst rqst = { 0 }; 4122498b56bSopenharmony_ci context.ToOutputRqst(rqst); 4132498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::OUTPUT_RQST, IoctlCmd::OUTPUT_RSP); 4142498b56bSopenharmony_ci int ret = ioctl.RequestOutput(rqst, [&context](const OutputRsp& rsp) { 4152498b56bSopenharmony_ci if (rsp.end) { 4162498b56bSopenharmony_ci return RET_SUCCESS; 4172498b56bSopenharmony_ci } 4182498b56bSopenharmony_ci LogContent content = { 4192498b56bSopenharmony_ci .level = rsp.level, 4202498b56bSopenharmony_ci .type = rsp.type, 4212498b56bSopenharmony_ci .pid = rsp.pid, 4222498b56bSopenharmony_ci .tid = rsp.tid, 4232498b56bSopenharmony_ci .domain = rsp.domain, 4242498b56bSopenharmony_ci .tv_sec = rsp.tv_sec, 4252498b56bSopenharmony_ci .tv_nsec = rsp.tv_nsec, 4262498b56bSopenharmony_ci .mono_sec = rsp.mono_sec, 4272498b56bSopenharmony_ci .tag = rsp.data, 4282498b56bSopenharmony_ci .log = (rsp.data + rsp.tagLen) 4292498b56bSopenharmony_ci }; 4302498b56bSopenharmony_ci LogFormat format = { 4312498b56bSopenharmony_ci .colorful = context.colorful, 4322498b56bSopenharmony_ci .timeFormat = ((context.timeFormat == FormatTime::INVALID) ? FormatTime::TIME : context.timeFormat), 4332498b56bSopenharmony_ci .timeAccuFormat = 4342498b56bSopenharmony_ci ((context.timeAccuFormat == FormatTimeAccu::INVALID) ? FormatTimeAccu::MSEC : context.timeAccuFormat), 4352498b56bSopenharmony_ci .year = context.year, 4362498b56bSopenharmony_ci .zone = context.zone, 4372498b56bSopenharmony_ci .wrap = context.wrap 4382498b56bSopenharmony_ci }; 4392498b56bSopenharmony_ci LogPrintWithFormat(content, format); 4402498b56bSopenharmony_ci return static_cast<int>(SUCCESS_CONTINUE); 4412498b56bSopenharmony_ci }); 4422498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 4432498b56bSopenharmony_ci return ret; 4442498b56bSopenharmony_ci } 4452498b56bSopenharmony_ci return RET_SUCCESS; 4462498b56bSopenharmony_ci} 4472498b56bSopenharmony_ci 4482498b56bSopenharmony_cistatic int HeadHandler(HilogArgs& context, const char *arg) 4492498b56bSopenharmony_ci{ 4502498b56bSopenharmony_ci if (IsNumericStr(arg) == false) { 4512498b56bSopenharmony_ci return ERR_NOT_NUMBER_STR; 4522498b56bSopenharmony_ci } 4532498b56bSopenharmony_ci int lines = 0; 4542498b56bSopenharmony_ci (void)StrToInt(arg, lines); 4552498b56bSopenharmony_ci context.headLines = static_cast<uint16_t>(lines); 4562498b56bSopenharmony_ci context.noBlock = true; // don't block implicitly 4572498b56bSopenharmony_ci return QueryLogHandler(context, arg); 4582498b56bSopenharmony_ci} 4592498b56bSopenharmony_ci 4602498b56bSopenharmony_cistatic int BaseLogLevelHandler(HilogArgs& context, const char *arg) 4612498b56bSopenharmony_ci{ 4622498b56bSopenharmony_ci uint16_t baseLevel = PrettyStr2LogLevel(arg); 4632498b56bSopenharmony_ci if (baseLevel == LOG_LEVEL_MIN) { 4642498b56bSopenharmony_ci return ERR_LOG_LEVEL_INVALID; 4652498b56bSopenharmony_ci } 4662498b56bSopenharmony_ci context.baseLevel = baseLevel; 4672498b56bSopenharmony_ci int ret; 4682498b56bSopenharmony_ci if (context.domainCount == 0 && context.tagCount == 0) { 4692498b56bSopenharmony_ci ret = SetGlobalLevel(context.baseLevel); 4702498b56bSopenharmony_ci PrintResult(ret, (string("Set global log level to ") + arg)); 4712498b56bSopenharmony_ci } 4722498b56bSopenharmony_ci if (context.domainCount != 0) { 4732498b56bSopenharmony_ci for (int i = 0; i < context.domainCount; i++) { 4742498b56bSopenharmony_ci ret = SetDomainLevel(context.domains[i], context.baseLevel); 4752498b56bSopenharmony_ci PrintResult(ret, (string("Set domain 0x") + Uint2HexStr(context.domains[i]) + " log level to " + arg)); 4762498b56bSopenharmony_ci } 4772498b56bSopenharmony_ci } 4782498b56bSopenharmony_ci if (context.tagCount != 0) { 4792498b56bSopenharmony_ci for (int i = 0; i < context.tagCount; i++) { 4802498b56bSopenharmony_ci ret = SetTagLevel(context.tags[i], context.baseLevel); 4812498b56bSopenharmony_ci PrintResult(ret, (string("Set tag ") + context.tags[i] + " log level to " + arg)); 4822498b56bSopenharmony_ci } 4832498b56bSopenharmony_ci } 4842498b56bSopenharmony_ci return RET_SUCCESS; 4852498b56bSopenharmony_ci} 4862498b56bSopenharmony_ci 4872498b56bSopenharmony_cistatic constexpr char BLACK_PREFIX = '^'; 4882498b56bSopenharmony_cistatic int DomainHandler(HilogArgs& context, const char *arg) 4892498b56bSopenharmony_ci{ 4902498b56bSopenharmony_ci context.blackDomain = (arg[0] == BLACK_PREFIX); 4912498b56bSopenharmony_ci std::vector<std::string> domains; 4922498b56bSopenharmony_ci Split(context.blackDomain ? arg + 1 : arg, domains); 4932498b56bSopenharmony_ci if (domains.size() == 0) { 4942498b56bSopenharmony_ci return ERR_INVALID_ARGUMENT; 4952498b56bSopenharmony_ci } 4962498b56bSopenharmony_ci int index = 0; 4972498b56bSopenharmony_ci for (string d : domains) { 4982498b56bSopenharmony_ci if (index >= MAX_DOMAINS) { 4992498b56bSopenharmony_ci return ERR_TOO_MANY_DOMAINS; 5002498b56bSopenharmony_ci } 5012498b56bSopenharmony_ci uint32_t domain = HexStr2Uint(d); 5022498b56bSopenharmony_ci if (domain == 0) { 5032498b56bSopenharmony_ci return ERR_INVALID_DOMAIN_STR; 5042498b56bSopenharmony_ci } 5052498b56bSopenharmony_ci context.domains[index++] = domain; 5062498b56bSopenharmony_ci } 5072498b56bSopenharmony_ci context.domainCount = index; 5082498b56bSopenharmony_ci return RET_SUCCESS; 5092498b56bSopenharmony_ci} 5102498b56bSopenharmony_ci 5112498b56bSopenharmony_cistatic int RegexHandler(HilogArgs& context, const char *arg) 5122498b56bSopenharmony_ci{ 5132498b56bSopenharmony_ci context.regex = arg; 5142498b56bSopenharmony_ci if (context.regex.length() >= MAX_REGEX_STR_LEN) { 5152498b56bSopenharmony_ci return ERR_REGEX_STR_TOO_LONG; 5162498b56bSopenharmony_ci } 5172498b56bSopenharmony_ci return RET_SUCCESS; 5182498b56bSopenharmony_ci} 5192498b56bSopenharmony_ci 5202498b56bSopenharmony_cistatic int FileNameHandler(HilogArgs& context, const char *arg) 5212498b56bSopenharmony_ci{ 5222498b56bSopenharmony_ci context.fileName = arg; 5232498b56bSopenharmony_ci if (context.fileName.length() >= MAX_FILE_NAME_LEN) { 5242498b56bSopenharmony_ci return ERR_FILE_NAME_TOO_LONG; 5252498b56bSopenharmony_ci } 5262498b56bSopenharmony_ci return RET_SUCCESS; 5272498b56bSopenharmony_ci} 5282498b56bSopenharmony_ci 5292498b56bSopenharmony_cistatic int BufferSizeGetHandler(HilogArgs& context, const char *arg) 5302498b56bSopenharmony_ci{ 5312498b56bSopenharmony_ci BufferSizeGetRqst rqst = { 0 }; 5322498b56bSopenharmony_ci context.ToBufferSizeGetRqst(rqst); 5332498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::BUFFERSIZE_GET_RQST, IoctlCmd::BUFFERSIZE_GET_RSP); 5342498b56bSopenharmony_ci int ret = ioctl.Request<BufferSizeGetRqst, BufferSizeGetRsp>(rqst, [&rqst](const BufferSizeGetRsp& rsp) { 5352498b56bSopenharmony_ci for (uint16_t i = 0; i < static_cast<uint16_t>(LOG_TYPE_MAX); i++) { 5362498b56bSopenharmony_ci if (rsp.size[i] > 0) { 5372498b56bSopenharmony_ci cout << "Log type " << LogType2Str(i) << " buffer size is " << Size2Str(rsp.size[i]) << endl; 5382498b56bSopenharmony_ci } 5392498b56bSopenharmony_ci } 5402498b56bSopenharmony_ci return RET_SUCCESS; 5412498b56bSopenharmony_ci }); 5422498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 5432498b56bSopenharmony_ci cout << "Get " << ComboLogType2Str(rqst.types) << " buffer size failed" << endl; 5442498b56bSopenharmony_ci } 5452498b56bSopenharmony_ci return ret; 5462498b56bSopenharmony_ci} 5472498b56bSopenharmony_ci 5482498b56bSopenharmony_cistatic int BufferSizeSetHandler(HilogArgs& context, const char *arg) 5492498b56bSopenharmony_ci{ 5502498b56bSopenharmony_ci uint64_t size = Str2Size(arg); 5512498b56bSopenharmony_ci if (size == 0) { 5522498b56bSopenharmony_ci return ERR_INVALID_SIZE_STR; 5532498b56bSopenharmony_ci } 5542498b56bSopenharmony_ci context.buffSize = static_cast<int32_t>(size); 5552498b56bSopenharmony_ci BufferSizeSetRqst rqst; 5562498b56bSopenharmony_ci context.ToBufferSizeSetRqst(rqst); 5572498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::BUFFERSIZE_SET_RQST, IoctlCmd::BUFFERSIZE_SET_RSP); 5582498b56bSopenharmony_ci int ret = ioctl.Request<BufferSizeSetRqst, BufferSizeSetRsp>(rqst, [&rqst](const BufferSizeSetRsp& rsp) { 5592498b56bSopenharmony_ci for (uint16_t i = 0; i < static_cast<uint16_t>(LOG_TYPE_MAX); i++) { 5602498b56bSopenharmony_ci if (rsp.size[i] > 0) { 5612498b56bSopenharmony_ci cout << "Set log type " << LogType2Str(i) << " buffer size to " 5622498b56bSopenharmony_ci << Size2Str(rsp.size[i]) << " successfully" << endl; 5632498b56bSopenharmony_ci } else if (rsp.size[i] < 0) { 5642498b56bSopenharmony_ci cout << "Set log type " << LogType2Str(i) << " buffer size to " 5652498b56bSopenharmony_ci << Size2Str(rqst.size) << " failed" << endl; 5662498b56bSopenharmony_ci PrintErr(rsp.size[i]); 5672498b56bSopenharmony_ci } 5682498b56bSopenharmony_ci } 5692498b56bSopenharmony_ci return RET_SUCCESS; 5702498b56bSopenharmony_ci }); 5712498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 5722498b56bSopenharmony_ci cout << "Set buffer size failed" << endl; 5732498b56bSopenharmony_ci } 5742498b56bSopenharmony_ci return ret; 5752498b56bSopenharmony_ci} 5762498b56bSopenharmony_ci 5772498b56bSopenharmony_cistatic int HelpHandler(HilogArgs& context, const char *arg) 5782498b56bSopenharmony_ci{ 5792498b56bSopenharmony_ci Helper(""); 5802498b56bSopenharmony_ci return RET_SUCCESS; 5812498b56bSopenharmony_ci} 5822498b56bSopenharmony_ci 5832498b56bSopenharmony_cistatic int JobIdHandler(HilogArgs& context, const char *arg) 5842498b56bSopenharmony_ci{ 5852498b56bSopenharmony_ci if (IsNumericStr(arg) == false) { 5862498b56bSopenharmony_ci return ERR_NOT_NUMBER_STR; 5872498b56bSopenharmony_ci } 5882498b56bSopenharmony_ci int jobId = 0; 5892498b56bSopenharmony_ci (void)StrToInt(arg, jobId); 5902498b56bSopenharmony_ci context.jobId = static_cast<uint32_t>(jobId); 5912498b56bSopenharmony_ci return RET_SUCCESS; 5922498b56bSopenharmony_ci} 5932498b56bSopenharmony_ci 5942498b56bSopenharmony_cistatic const string FEATURE_ON = "on"; 5952498b56bSopenharmony_cistatic const string FEATURE_OFF = "off"; 5962498b56bSopenharmony_cistatic int KmsgFeatureSetHandler(HilogArgs& context, const char *arg) 5972498b56bSopenharmony_ci{ 5982498b56bSopenharmony_ci string argStr = arg; 5992498b56bSopenharmony_ci bool kmsgOn = true; 6002498b56bSopenharmony_ci if (argStr == FEATURE_ON) { 6012498b56bSopenharmony_ci kmsgOn = true; 6022498b56bSopenharmony_ci } else if (argStr == FEATURE_OFF) { 6032498b56bSopenharmony_ci kmsgOn = false; 6042498b56bSopenharmony_ci } else { 6052498b56bSopenharmony_ci return ERR_INVALID_ARGUMENT; 6062498b56bSopenharmony_ci } 6072498b56bSopenharmony_ci KmsgEnableRqst rqst = { kmsgOn }; 6082498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::KMSG_ENABLE_RQST, IoctlCmd::KMSG_ENABLE_RSP); 6092498b56bSopenharmony_ci int ret = ioctl.Request<KmsgEnableRqst, KmsgEnableRsp>(rqst, [&rqst](const KmsgEnableRsp& rsp) { 6102498b56bSopenharmony_ci return RET_SUCCESS; 6112498b56bSopenharmony_ci }); 6122498b56bSopenharmony_ci PrintResult(ret, (string("Set hilogd storing kmsg log ") + arg)); 6132498b56bSopenharmony_ci return ret; 6142498b56bSopenharmony_ci} 6152498b56bSopenharmony_ci 6162498b56bSopenharmony_cistatic int FileLengthHandler(HilogArgs& context, const char *arg) 6172498b56bSopenharmony_ci{ 6182498b56bSopenharmony_ci uint64_t size = Str2Size(arg); 6192498b56bSopenharmony_ci if (size == 0) { 6202498b56bSopenharmony_ci return ERR_INVALID_SIZE_STR; 6212498b56bSopenharmony_ci } 6222498b56bSopenharmony_ci context.fileSize = size; 6232498b56bSopenharmony_ci return RET_SUCCESS; 6242498b56bSopenharmony_ci} 6252498b56bSopenharmony_ci 6262498b56bSopenharmony_cistatic int LevelHandler(HilogArgs& context, const char *arg) 6272498b56bSopenharmony_ci{ 6282498b56bSopenharmony_ci uint16_t levels = Str2ComboLogLevel(arg); 6292498b56bSopenharmony_ci if (levels == 0) { 6302498b56bSopenharmony_ci return ERR_LOG_LEVEL_INVALID; 6312498b56bSopenharmony_ci } 6322498b56bSopenharmony_ci context.levels = levels; 6332498b56bSopenharmony_ci return RET_SUCCESS; 6342498b56bSopenharmony_ci} 6352498b56bSopenharmony_ci 6362498b56bSopenharmony_cistatic int FileCompressHandler(HilogArgs& context, const char *arg) 6372498b56bSopenharmony_ci{ 6382498b56bSopenharmony_ci context.stream = arg; 6392498b56bSopenharmony_ci return RET_SUCCESS; 6402498b56bSopenharmony_ci} 6412498b56bSopenharmony_ci 6422498b56bSopenharmony_cistatic int FileNumberHandler(HilogArgs& context, const char *arg) 6432498b56bSopenharmony_ci{ 6442498b56bSopenharmony_ci if (IsNumericStr(arg) == false) { 6452498b56bSopenharmony_ci return ERR_NOT_NUMBER_STR; 6462498b56bSopenharmony_ci } 6472498b56bSopenharmony_ci int fileNum = 0; 6482498b56bSopenharmony_ci (void)StrToInt(arg, fileNum); 6492498b56bSopenharmony_ci context.fileNum = static_cast<uint16_t>(fileNum); 6502498b56bSopenharmony_ci return RET_SUCCESS; 6512498b56bSopenharmony_ci} 6522498b56bSopenharmony_ci 6532498b56bSopenharmony_cistatic int PrivateFeatureSetHandler(HilogArgs& context, const char *arg) 6542498b56bSopenharmony_ci{ 6552498b56bSopenharmony_ci string argStr = arg; 6562498b56bSopenharmony_ci bool privateOn = true; 6572498b56bSopenharmony_ci if (argStr == FEATURE_ON) { 6582498b56bSopenharmony_ci privateOn = true; 6592498b56bSopenharmony_ci } else if (argStr == FEATURE_OFF) { 6602498b56bSopenharmony_ci privateOn = false; 6612498b56bSopenharmony_ci } else { 6622498b56bSopenharmony_ci return ERR_INVALID_ARGUMENT; 6632498b56bSopenharmony_ci } 6642498b56bSopenharmony_ci int ret = SetPrivateSwitchOn(privateOn); 6652498b56bSopenharmony_ci PrintResult(ret, (string("Set hilog privacy format ") + arg)); 6662498b56bSopenharmony_ci return RET_SUCCESS; 6672498b56bSopenharmony_ci} 6682498b56bSopenharmony_ci 6692498b56bSopenharmony_cistatic int PidHandler(HilogArgs& context, const char *arg) 6702498b56bSopenharmony_ci{ 6712498b56bSopenharmony_ci context.blackPid = (arg[0] == BLACK_PREFIX); 6722498b56bSopenharmony_ci std::vector<std::string> pids; 6732498b56bSopenharmony_ci Split(context.blackPid ? arg + 1 : arg, pids); 6742498b56bSopenharmony_ci if (pids.size() == 0) { 6752498b56bSopenharmony_ci return ERR_INVALID_ARGUMENT; 6762498b56bSopenharmony_ci } 6772498b56bSopenharmony_ci int index = 0; 6782498b56bSopenharmony_ci for (string p : pids) { 6792498b56bSopenharmony_ci if (index >= MAX_PIDS) { 6802498b56bSopenharmony_ci return ERR_TOO_MANY_PIDS; 6812498b56bSopenharmony_ci } 6822498b56bSopenharmony_ci if (IsNumericStr(p) == false) { 6832498b56bSopenharmony_ci return ERR_NOT_NUMBER_STR; 6842498b56bSopenharmony_ci } 6852498b56bSopenharmony_ci int pid = 0; 6862498b56bSopenharmony_ci (void)StrToInt(p, pid); 6872498b56bSopenharmony_ci context.pids[index++] = static_cast<uint32_t>(pid); 6882498b56bSopenharmony_ci } 6892498b56bSopenharmony_ci context.pidCount = index; 6902498b56bSopenharmony_ci return RET_SUCCESS; 6912498b56bSopenharmony_ci} 6922498b56bSopenharmony_ci 6932498b56bSopenharmony_cistatic int SetDomainFlowCtrl(bool on) 6942498b56bSopenharmony_ci{ 6952498b56bSopenharmony_ci DomainFlowCtrlRqst rqst = { 0 }; 6962498b56bSopenharmony_ci rqst.on = on; 6972498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::DOMAIN_FLOWCTRL_RQST, IoctlCmd::DOMAIN_FLOWCTRL_RSP); 6982498b56bSopenharmony_ci int ret = ioctl.Request<DomainFlowCtrlRqst, DomainFlowCtrlRsp>(rqst, [&rqst](const DomainFlowCtrlRsp& rsp) { 6992498b56bSopenharmony_ci return RET_SUCCESS; 7002498b56bSopenharmony_ci }); 7012498b56bSopenharmony_ci return ret; 7022498b56bSopenharmony_ci} 7032498b56bSopenharmony_cistatic int FlowControlFeatureSetHandler(HilogArgs& context, const char *arg) 7042498b56bSopenharmony_ci{ 7052498b56bSopenharmony_ci string pid = "pid"; 7062498b56bSopenharmony_ci string domain = "domain"; 7072498b56bSopenharmony_ci string argStr = arg; 7082498b56bSopenharmony_ci int ret; 7092498b56bSopenharmony_ci if (argStr == (pid + FEATURE_ON)) { 7102498b56bSopenharmony_ci ret = SetProcessSwitchOn(true); 7112498b56bSopenharmony_ci cout << "Set flow control by process to enabled, result: " << ErrorCode2Str(ret) << endl; 7122498b56bSopenharmony_ci } else if (argStr == (pid + FEATURE_OFF)) { 7132498b56bSopenharmony_ci ret = SetProcessSwitchOn(false); 7142498b56bSopenharmony_ci cout << "Set flow control by process to disabled, result: " << ErrorCode2Str(ret) << endl; 7152498b56bSopenharmony_ci } else if (argStr == (domain + FEATURE_ON)) { 7162498b56bSopenharmony_ci ret = SetDomainFlowCtrl(true); 7172498b56bSopenharmony_ci cout << "Set flow control by domain to enabled, result: " << ErrorCode2Str(ret) << endl; 7182498b56bSopenharmony_ci } else if (argStr == (domain + FEATURE_OFF)) { 7192498b56bSopenharmony_ci ret = SetDomainFlowCtrl(false); 7202498b56bSopenharmony_ci cout << "Set flow control by domain to disabled, result: " << ErrorCode2Str(ret) << endl; 7212498b56bSopenharmony_ci } else { 7222498b56bSopenharmony_ci return ERR_INVALID_ARGUMENT; 7232498b56bSopenharmony_ci } 7242498b56bSopenharmony_ci return ret; 7252498b56bSopenharmony_ci} 7262498b56bSopenharmony_ci 7272498b56bSopenharmony_cistatic int RemoveHandler(HilogArgs& context, const char *arg) 7282498b56bSopenharmony_ci{ 7292498b56bSopenharmony_ci LogRemoveRqst rqst = { 0 }; 7302498b56bSopenharmony_ci context.ToLogRemoveRqst(rqst); 7312498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::LOG_REMOVE_RQST, IoctlCmd::LOG_REMOVE_RSP); 7322498b56bSopenharmony_ci int ret = ioctl.Request<LogRemoveRqst, LogRemoveRsp>(rqst, [&rqst](const LogRemoveRsp& rsp) { 7332498b56bSopenharmony_ci cout << "Log type " << ComboLogType2Str(rsp.types) << " buffer clear successfully" << endl; 7342498b56bSopenharmony_ci return RET_SUCCESS; 7352498b56bSopenharmony_ci }); 7362498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 7372498b56bSopenharmony_ci cout << "Log buffer clear failed" << endl; 7382498b56bSopenharmony_ci } 7392498b56bSopenharmony_ci return ret; 7402498b56bSopenharmony_ci} 7412498b56bSopenharmony_ci 7422498b56bSopenharmony_cistatic int StatsInfoQueryHandler(HilogArgs& context, const char *arg) 7432498b56bSopenharmony_ci{ 7442498b56bSopenharmony_ci StatsQueryRqst rqst = { 0 }; 7452498b56bSopenharmony_ci context.ToStatsQueryRqst(rqst); 7462498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::STATS_QUERY_RQST, IoctlCmd::STATS_QUERY_RSP); 7472498b56bSopenharmony_ci int ret = ioctl.RequestStatsQuery(rqst, [&rqst](const StatsQueryRsp& rsp) { 7482498b56bSopenharmony_ci HilogShowLogStatsInfo(rsp); 7492498b56bSopenharmony_ci return RET_SUCCESS; 7502498b56bSopenharmony_ci }); 7512498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 7522498b56bSopenharmony_ci cout << "Statistic info query failed" << endl; 7532498b56bSopenharmony_ci } 7542498b56bSopenharmony_ci return ret; 7552498b56bSopenharmony_ci} 7562498b56bSopenharmony_ci 7572498b56bSopenharmony_cistatic int StatsInfoClearHandler(HilogArgs& context, const char *arg) 7582498b56bSopenharmony_ci{ 7592498b56bSopenharmony_ci StatsClearRqst rqst = { 0 }; 7602498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::STATS_CLEAR_RQST, IoctlCmd::STATS_CLEAR_RSP); 7612498b56bSopenharmony_ci int ret = ioctl.Request<StatsClearRqst, StatsClearRsp>(rqst, [&rqst](const StatsClearRsp& rsp) { 7622498b56bSopenharmony_ci cout << "Statistic info clear successfully" << endl; 7632498b56bSopenharmony_ci return RET_SUCCESS; 7642498b56bSopenharmony_ci }); 7652498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 7662498b56bSopenharmony_ci cout << "Statistic info clear failed" << endl; 7672498b56bSopenharmony_ci } 7682498b56bSopenharmony_ci return ret; 7692498b56bSopenharmony_ci} 7702498b56bSopenharmony_ci 7712498b56bSopenharmony_cistatic int TypeHandler(HilogArgs& context, const char *arg) 7722498b56bSopenharmony_ci{ 7732498b56bSopenharmony_ci uint16_t types = Str2ComboLogType(arg); 7742498b56bSopenharmony_ci if (types == 0) { 7752498b56bSopenharmony_ci return ERR_LOG_TYPE_INVALID; 7762498b56bSopenharmony_ci } 7772498b56bSopenharmony_ci context.types = types; 7782498b56bSopenharmony_ci return RET_SUCCESS; 7792498b56bSopenharmony_ci} 7802498b56bSopenharmony_ci 7812498b56bSopenharmony_cistatic int TagHandler(HilogArgs& context, const char *arg) 7822498b56bSopenharmony_ci{ 7832498b56bSopenharmony_ci context.blackTag = (arg[0] == BLACK_PREFIX); 7842498b56bSopenharmony_ci std::vector<std::string> tags; 7852498b56bSopenharmony_ci Split(context.blackTag ? arg + 1 : arg, tags); 7862498b56bSopenharmony_ci int index = 0; 7872498b56bSopenharmony_ci for (string t : tags) { 7882498b56bSopenharmony_ci if (index >= MAX_TAGS) { 7892498b56bSopenharmony_ci return ERR_TOO_MANY_TAGS; 7902498b56bSopenharmony_ci } 7912498b56bSopenharmony_ci if (t.length() >= MAX_TAG_LEN) { 7922498b56bSopenharmony_ci return ERR_TAG_STR_TOO_LONG; 7932498b56bSopenharmony_ci } 7942498b56bSopenharmony_ci context.tags[index++] = t; 7952498b56bSopenharmony_ci } 7962498b56bSopenharmony_ci context.tagCount = index; 7972498b56bSopenharmony_ci return RET_SUCCESS; 7982498b56bSopenharmony_ci} 7992498b56bSopenharmony_ci 8002498b56bSopenharmony_cistatic int TimeHandler(HilogArgs& context, FormatTime value) 8012498b56bSopenharmony_ci{ 8022498b56bSopenharmony_ci if (context.timeFormat != FormatTime::INVALID) { 8032498b56bSopenharmony_ci return ERR_DUPLICATE_OPTION; 8042498b56bSopenharmony_ci } 8052498b56bSopenharmony_ci context.timeFormat = value; 8062498b56bSopenharmony_ci return RET_SUCCESS; 8072498b56bSopenharmony_ci} 8082498b56bSopenharmony_ci 8092498b56bSopenharmony_cistatic int TimeAccuHandler(HilogArgs& context, FormatTimeAccu value) 8102498b56bSopenharmony_ci{ 8112498b56bSopenharmony_ci if (context.timeAccuFormat != FormatTimeAccu::INVALID) { 8122498b56bSopenharmony_ci return ERR_DUPLICATE_OPTION; 8132498b56bSopenharmony_ci } 8142498b56bSopenharmony_ci context.timeAccuFormat = value; 8152498b56bSopenharmony_ci return RET_SUCCESS; 8162498b56bSopenharmony_ci} 8172498b56bSopenharmony_ci 8182498b56bSopenharmony_cistatic int FormatHandler(HilogArgs& context, const char *arg) 8192498b56bSopenharmony_ci{ 8202498b56bSopenharmony_ci static std::unordered_map<std::string, std::function<int(HilogArgs&, int)>> handlers = { 8212498b56bSopenharmony_ci {"color", [] (HilogArgs& context, int value) { 8222498b56bSopenharmony_ci context.colorful = true; 8232498b56bSopenharmony_ci return RET_SUCCESS; 8242498b56bSopenharmony_ci }}, 8252498b56bSopenharmony_ci {"colour", [] (HilogArgs& context, int value) { 8262498b56bSopenharmony_ci context.colorful = true; 8272498b56bSopenharmony_ci return RET_SUCCESS; 8282498b56bSopenharmony_ci }}, 8292498b56bSopenharmony_ci {"time", [] (HilogArgs& context, int value) { 8302498b56bSopenharmony_ci return TimeHandler(context, FormatTime::TIME); 8312498b56bSopenharmony_ci }}, 8322498b56bSopenharmony_ci {"epoch", [] (HilogArgs& context, int value) { 8332498b56bSopenharmony_ci return TimeHandler(context, FormatTime::EPOCH); 8342498b56bSopenharmony_ci }}, 8352498b56bSopenharmony_ci {"monotonic", [] (HilogArgs& context, int value) { 8362498b56bSopenharmony_ci return TimeHandler(context, FormatTime::MONOTONIC); 8372498b56bSopenharmony_ci }}, 8382498b56bSopenharmony_ci {"msec", [] (HilogArgs& context, int value) { 8392498b56bSopenharmony_ci return TimeAccuHandler(context, FormatTimeAccu::MSEC); 8402498b56bSopenharmony_ci }}, 8412498b56bSopenharmony_ci {"usec", [] (HilogArgs& context, int value) { 8422498b56bSopenharmony_ci return TimeAccuHandler(context, FormatTimeAccu::USEC); 8432498b56bSopenharmony_ci }}, 8442498b56bSopenharmony_ci {"nsec", [] (HilogArgs& context, int value) { 8452498b56bSopenharmony_ci return TimeAccuHandler(context, FormatTimeAccu::NSEC); 8462498b56bSopenharmony_ci }}, 8472498b56bSopenharmony_ci {"year", [] (HilogArgs& context, int value) { 8482498b56bSopenharmony_ci context.year = true; 8492498b56bSopenharmony_ci return RET_SUCCESS; 8502498b56bSopenharmony_ci }}, 8512498b56bSopenharmony_ci {"zone", [] (HilogArgs& context, int value) { 8522498b56bSopenharmony_ci context.zone = true; 8532498b56bSopenharmony_ci tzset(); 8542498b56bSopenharmony_ci return RET_SUCCESS; 8552498b56bSopenharmony_ci }}, 8562498b56bSopenharmony_ci {"wrap", [] (HilogArgs& context, int value) { 8572498b56bSopenharmony_ci context.wrap = true; 8582498b56bSopenharmony_ci return RET_SUCCESS; 8592498b56bSopenharmony_ci }}, 8602498b56bSopenharmony_ci }; 8612498b56bSopenharmony_ci 8622498b56bSopenharmony_ci auto handler = handlers.find(arg); 8632498b56bSopenharmony_ci if (handler == handlers.end() || handler->second == nullptr) { 8642498b56bSopenharmony_ci return ERR_INVALID_ARGUMENT; 8652498b56bSopenharmony_ci } 8662498b56bSopenharmony_ci return handler->second(context, 0); 8672498b56bSopenharmony_ci} 8682498b56bSopenharmony_ci 8692498b56bSopenharmony_cistatic int PersistTaskStart(HilogArgs& context) 8702498b56bSopenharmony_ci{ 8712498b56bSopenharmony_ci PersistStartRqst rqst = { { 0 }, 0 }; 8722498b56bSopenharmony_ci context.ToPersistStartRqst(rqst); 8732498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::PERSIST_START_RQST, IoctlCmd::PERSIST_START_RSP); 8742498b56bSopenharmony_ci int ret = ioctl.Request<PersistStartRqst, PersistStartRsp>(rqst, [&rqst](const PersistStartRsp& rsp) { 8752498b56bSopenharmony_ci cout << "Persist task [jobid:" << rsp.jobId << "] start successfully" << endl; 8762498b56bSopenharmony_ci return RET_SUCCESS; 8772498b56bSopenharmony_ci }); 8782498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 8792498b56bSopenharmony_ci cout << "Persist task start failed" << endl; 8802498b56bSopenharmony_ci } 8812498b56bSopenharmony_ci return ret; 8822498b56bSopenharmony_ci} 8832498b56bSopenharmony_ci 8842498b56bSopenharmony_cistatic int PersistTaskStop(HilogArgs& context) 8852498b56bSopenharmony_ci{ 8862498b56bSopenharmony_ci PersistStopRqst rqst = { 0 }; 8872498b56bSopenharmony_ci context.ToPersistStopRqst(rqst); 8882498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::PERSIST_STOP_RQST, IoctlCmd::PERSIST_STOP_RSP); 8892498b56bSopenharmony_ci int ret = ioctl.Request<PersistStopRqst, PersistStopRsp>(rqst, [&rqst](const PersistStopRsp& rsp) { 8902498b56bSopenharmony_ci for (int i = 0; i < rsp.jobNum; i++) { 8912498b56bSopenharmony_ci cout << "Persist task [jobid:" << rsp.jobId[i] << "] stop successfully" << endl; 8922498b56bSopenharmony_ci } 8932498b56bSopenharmony_ci return RET_SUCCESS; 8942498b56bSopenharmony_ci }); 8952498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 8962498b56bSopenharmony_ci cout << "Persist task stop failed" << endl; 8972498b56bSopenharmony_ci } 8982498b56bSopenharmony_ci return ret; 8992498b56bSopenharmony_ci} 9002498b56bSopenharmony_ci 9012498b56bSopenharmony_cistatic void PrintTaskInfo(const PersistTaskInfo& task) 9022498b56bSopenharmony_ci{ 9032498b56bSopenharmony_ci cout << task.jobId << " " << ComboLogType2Str(task.outputFilter.types) << " " << task.stream << " "; 9042498b56bSopenharmony_ci cout << task.fileName << " " << Size2Str(task.fileSize) << " " << to_string(task.fileNum) << endl; 9052498b56bSopenharmony_ci} 9062498b56bSopenharmony_ci 9072498b56bSopenharmony_cistatic int PersistTaskQuery() 9082498b56bSopenharmony_ci{ 9092498b56bSopenharmony_ci PersistQueryRqst rqst = { 0 }; 9102498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::PERSIST_QUERY_RQST, IoctlCmd::PERSIST_QUERY_RSP); 9112498b56bSopenharmony_ci int ret = ioctl.Request<PersistQueryRqst, PersistQueryRsp>(rqst, [&rqst](const PersistQueryRsp& rsp) { 9122498b56bSopenharmony_ci for (int i = 0; i < rsp.jobNum; i++) { 9132498b56bSopenharmony_ci PrintTaskInfo(rsp.taskInfo[i]); 9142498b56bSopenharmony_ci } 9152498b56bSopenharmony_ci return RET_SUCCESS; 9162498b56bSopenharmony_ci }); 9172498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 9182498b56bSopenharmony_ci cout << "Persist task query failed" << endl; 9192498b56bSopenharmony_ci } 9202498b56bSopenharmony_ci return ret; 9212498b56bSopenharmony_ci} 9222498b56bSopenharmony_ci 9232498b56bSopenharmony_cistatic int PersistTaskRefresh() 9242498b56bSopenharmony_ci{ 9252498b56bSopenharmony_ci PersistRefreshRqst rqst = { 0 }; 9262498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::PERSIST_REFRESH_RQST, IoctlCmd::PERSIST_REFRESH_RSP); 9272498b56bSopenharmony_ci int ret = ioctl.Request<PersistRefreshRqst, PersistRefreshRsp>(rqst, [&rqst](const PersistRefreshRsp& rsp) { 9282498b56bSopenharmony_ci for (int i = 0; i < rsp.jobNum; i++) { 9292498b56bSopenharmony_ci PrintResult(RET_SUCCESS, (string("Persist task [jobid:") + to_string(rsp.jobId[i]) + "] refresh")); 9302498b56bSopenharmony_ci } 9312498b56bSopenharmony_ci return RET_SUCCESS; 9322498b56bSopenharmony_ci }); 9332498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 9342498b56bSopenharmony_ci PrintResult(RET_FAIL, (string("Persist task refresh"))); 9352498b56bSopenharmony_ci } 9362498b56bSopenharmony_ci return ret; 9372498b56bSopenharmony_ci} 9382498b56bSopenharmony_ci 9392498b56bSopenharmony_cistatic int ClearPersistLog() 9402498b56bSopenharmony_ci{ 9412498b56bSopenharmony_ci PersistClearRqst rqst = { 0 }; 9422498b56bSopenharmony_ci LogIoctl ioctl(IoctlCmd::PERSIST_CLEAR_RQST, IoctlCmd::PERSIST_CLEAR_RSP); 9432498b56bSopenharmony_ci int ret = ioctl.Request<PersistClearRqst, PersistClearRsp>(rqst, [&rqst](const PersistClearRsp& rsp) { 9442498b56bSopenharmony_ci PrintResult(RET_SUCCESS, (string("Persist log /data/log/hilog clear"))); 9452498b56bSopenharmony_ci return RET_SUCCESS; 9462498b56bSopenharmony_ci }); 9472498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 9482498b56bSopenharmony_ci PrintResult(RET_FAIL, (string("Persist log /data/log/hilog clear"))); 9492498b56bSopenharmony_ci } 9502498b56bSopenharmony_ci return ret; 9512498b56bSopenharmony_ci} 9522498b56bSopenharmony_ci 9532498b56bSopenharmony_cistatic int PersistTaskHandler(HilogArgs& context, const char *arg) 9542498b56bSopenharmony_ci{ 9552498b56bSopenharmony_ci string strArg = arg; 9562498b56bSopenharmony_ci if (strArg == "start") { 9572498b56bSopenharmony_ci return PersistTaskStart(context); 9582498b56bSopenharmony_ci } else if (strArg == "stop") { 9592498b56bSopenharmony_ci return PersistTaskStop(context); 9602498b56bSopenharmony_ci } else if (strArg == "query") { 9612498b56bSopenharmony_ci return PersistTaskQuery(); 9622498b56bSopenharmony_ci } else if (strArg == "refresh") { 9632498b56bSopenharmony_ci return PersistTaskRefresh(); 9642498b56bSopenharmony_ci } else if (strArg == "clear") { 9652498b56bSopenharmony_ci return ClearPersistLog(); 9662498b56bSopenharmony_ci } else { 9672498b56bSopenharmony_ci return ERR_INVALID_ARGUMENT; 9682498b56bSopenharmony_ci } 9692498b56bSopenharmony_ci return RET_SUCCESS; 9702498b56bSopenharmony_ci} 9712498b56bSopenharmony_ci 9722498b56bSopenharmony_cistatic int NoBlockHandler(HilogArgs& context, const char *arg) 9732498b56bSopenharmony_ci{ 9742498b56bSopenharmony_ci context.noBlock = true; 9752498b56bSopenharmony_ci return QueryLogHandler(context, arg); 9762498b56bSopenharmony_ci} 9772498b56bSopenharmony_ci 9782498b56bSopenharmony_cistatic int TailHandler(HilogArgs& context, const char *arg) 9792498b56bSopenharmony_ci{ 9802498b56bSopenharmony_ci if (IsNumericStr(arg) == false) { 9812498b56bSopenharmony_ci return ERR_NOT_NUMBER_STR; 9822498b56bSopenharmony_ci } 9832498b56bSopenharmony_ci int tailLines = 0; 9842498b56bSopenharmony_ci (void)StrToInt(arg, tailLines); 9852498b56bSopenharmony_ci context.tailLines = static_cast<uint16_t>(tailLines); 9862498b56bSopenharmony_ci context.noBlock = true; // don't block implicitly 9872498b56bSopenharmony_ci return QueryLogHandler(context, arg); 9882498b56bSopenharmony_ci} 9892498b56bSopenharmony_ci 9902498b56bSopenharmony_cistruct OptEntry { 9912498b56bSopenharmony_ci const char opt; 9922498b56bSopenharmony_ci const char *longOpt; 9932498b56bSopenharmony_ci const ControlCmd cmd; 9942498b56bSopenharmony_ci const OptHandler handler; 9952498b56bSopenharmony_ci const bool needArg; 9962498b56bSopenharmony_ci // how many times can this option be used, for example: 9972498b56bSopenharmony_ci // hilog -v msec -v color ... 9982498b56bSopenharmony_ci uint32_t count; 9992498b56bSopenharmony_ci}; 10002498b56bSopenharmony_cistatic OptEntry optEntries[] = { 10012498b56bSopenharmony_ci {'a', "head", ControlCmd::CMD_QUERY, HeadHandler, true, 1}, 10022498b56bSopenharmony_ci {'b', "baselevel", ControlCmd::CMD_LOGLEVEL_SET, BaseLogLevelHandler, true, 1}, 10032498b56bSopenharmony_ci {'D', "domain", ControlCmd::NOT_CMD, DomainHandler, true, 1}, 10042498b56bSopenharmony_ci {'e', "regex", ControlCmd::NOT_CMD, RegexHandler, true, 1}, 10052498b56bSopenharmony_ci {'f', "filename", ControlCmd::NOT_CMD, FileNameHandler, true, 1}, 10062498b56bSopenharmony_ci {'g', nullptr, ControlCmd::CMD_BUFFER_SIZE_QUERY, BufferSizeGetHandler, false, 1}, 10072498b56bSopenharmony_ci {'G', "buffer-size", ControlCmd::CMD_BUFFER_SIZE_SET, BufferSizeSetHandler, true, 1}, 10082498b56bSopenharmony_ci {'h', "help", ControlCmd::CMD_HELP, HelpHandler, false, 1}, 10092498b56bSopenharmony_ci {'j', "jobid", ControlCmd::NOT_CMD, JobIdHandler, true, 1}, 10102498b56bSopenharmony_ci {'k', "kmsg", ControlCmd::CMD_KMSG_FEATURE_SET, KmsgFeatureSetHandler, true, 1}, 10112498b56bSopenharmony_ci {'l', "length", ControlCmd::NOT_CMD, FileLengthHandler, true, 1}, 10122498b56bSopenharmony_ci {'L', "level", ControlCmd::NOT_CMD, LevelHandler, true, 1}, 10132498b56bSopenharmony_ci {'m', "stream", ControlCmd::NOT_CMD, FileCompressHandler, true, 1}, 10142498b56bSopenharmony_ci {'n', "number", ControlCmd::NOT_CMD, FileNumberHandler, true, 1}, 10152498b56bSopenharmony_ci {'p', "private", ControlCmd::CMD_PRIVATE_FEATURE_SET, PrivateFeatureSetHandler, true, 1}, 10162498b56bSopenharmony_ci {'P', "pid", ControlCmd::NOT_CMD, PidHandler, true, 1}, 10172498b56bSopenharmony_ci {'Q', "flowctrl", ControlCmd::CMD_FLOWCONTROL_FEATURE_SET, FlowControlFeatureSetHandler, true, 1}, 10182498b56bSopenharmony_ci {'r', nullptr, ControlCmd::CMD_REMOVE, RemoveHandler, false, 1}, 10192498b56bSopenharmony_ci {'s', "statistics", ControlCmd::CMD_STATS_INFO_QUERY, StatsInfoQueryHandler, false, 1}, 10202498b56bSopenharmony_ci {'S', nullptr, ControlCmd::CMD_STATS_INFO_CLEAR, StatsInfoClearHandler, false, 1}, 10212498b56bSopenharmony_ci {'t', "type", ControlCmd::NOT_CMD, TypeHandler, true, 1}, 10222498b56bSopenharmony_ci {'T', "tag", ControlCmd::NOT_CMD, TagHandler, true, 1}, 10232498b56bSopenharmony_ci {'v', "format", ControlCmd::NOT_CMD, FormatHandler, true, 5}, 10242498b56bSopenharmony_ci {'w', "write", ControlCmd::CMD_PERSIST_TASK, PersistTaskHandler, true, 1}, 10252498b56bSopenharmony_ci {'x', "exit", ControlCmd::CMD_QUERY, NoBlockHandler, false, 1}, 10262498b56bSopenharmony_ci {'z', "tail", ControlCmd::CMD_QUERY, TailHandler, true, 1}, 10272498b56bSopenharmony_ci {0, nullptr, ControlCmd::NOT_CMD, nullptr, false, 1}, // End default entry 10282498b56bSopenharmony_ci}; // "hxz:grsSa:v:e:t:L:G:f:l:n:j:w:p:k:D:T:b:Q:m:P:" 10292498b56bSopenharmony_cistatic constexpr int OPT_ENTRY_CNT = sizeof(optEntries) / sizeof(OptEntry); 10302498b56bSopenharmony_ci 10312498b56bSopenharmony_cistatic void GetOpts(string& opts, struct option(&longOptions)[OPT_ENTRY_CNT]) 10322498b56bSopenharmony_ci{ 10332498b56bSopenharmony_ci int longOptcount = 0; 10342498b56bSopenharmony_ci opts = ""; 10352498b56bSopenharmony_ci int i; 10362498b56bSopenharmony_ci for (i = 0; i < OPT_ENTRY_CNT; i++) { 10372498b56bSopenharmony_ci if (optEntries[i].opt == 0) { 10382498b56bSopenharmony_ci break; 10392498b56bSopenharmony_ci } 10402498b56bSopenharmony_ci // opts 10412498b56bSopenharmony_ci opts += optEntries[i].opt; 10422498b56bSopenharmony_ci if (optEntries[i].needArg) { 10432498b56bSopenharmony_ci opts += ':'; 10442498b56bSopenharmony_ci } 10452498b56bSopenharmony_ci // long option 10462498b56bSopenharmony_ci if (optEntries[i].longOpt == nullptr) { 10472498b56bSopenharmony_ci continue; 10482498b56bSopenharmony_ci } 10492498b56bSopenharmony_ci longOptions[longOptcount].name = optEntries[i].longOpt; 10502498b56bSopenharmony_ci longOptions[longOptcount].has_arg = optEntries[i].needArg ? required_argument : no_argument; 10512498b56bSopenharmony_ci longOptions[longOptcount].flag = nullptr; 10522498b56bSopenharmony_ci longOptions[longOptcount].val = optEntries[i].opt; 10532498b56bSopenharmony_ci longOptcount++; 10542498b56bSopenharmony_ci } 10552498b56bSopenharmony_ci longOptions[longOptcount].name = nullptr; 10562498b56bSopenharmony_ci longOptions[longOptcount].has_arg = 0; 10572498b56bSopenharmony_ci longOptions[longOptcount].flag = nullptr; 10582498b56bSopenharmony_ci longOptions[longOptcount].val = 0; 10592498b56bSopenharmony_ci return; 10602498b56bSopenharmony_ci} 10612498b56bSopenharmony_ci 10622498b56bSopenharmony_cistatic OptEntry* GetOptEntry(int choice) 10632498b56bSopenharmony_ci{ 10642498b56bSopenharmony_ci OptEntry *entry = &(optEntries[OPT_ENTRY_CNT - 1]); 10652498b56bSopenharmony_ci int i = 0; 10662498b56bSopenharmony_ci for (i = 0; i < OPT_ENTRY_CNT; i++) { 10672498b56bSopenharmony_ci if (optEntries[i].opt == static_cast<char>(choice)) { 10682498b56bSopenharmony_ci entry = &(optEntries[i]); 10692498b56bSopenharmony_ci break; 10702498b56bSopenharmony_ci } 10712498b56bSopenharmony_ci } 10722498b56bSopenharmony_ci return entry; 10732498b56bSopenharmony_ci} 10742498b56bSopenharmony_ci 10752498b56bSopenharmony_ciint HilogEntry(int argc, char* argv[]) 10762498b56bSopenharmony_ci{ 10772498b56bSopenharmony_ci struct option longOptions[OPT_ENTRY_CNT]; 10782498b56bSopenharmony_ci string opts; 10792498b56bSopenharmony_ci GetOpts(opts, longOptions); 10802498b56bSopenharmony_ci HilogArgs context; 10812498b56bSopenharmony_ci int optIndex = 0; 10822498b56bSopenharmony_ci 10832498b56bSopenharmony_ci // 0. help has special case 10842498b56bSopenharmony_ci static const int argCountHelp = 3; 10852498b56bSopenharmony_ci if (argc == argCountHelp) { 10862498b56bSopenharmony_ci string arg = argv[1]; 10872498b56bSopenharmony_ci if (arg == "--help" || arg == "-h") { 10882498b56bSopenharmony_ci Helper(argv[argCountHelp - 1]); 10892498b56bSopenharmony_ci return RET_SUCCESS; 10902498b56bSopenharmony_ci } 10912498b56bSopenharmony_ci } 10922498b56bSopenharmony_ci // 1. Scan all options and process NOT_CMD options' arguments 10932498b56bSopenharmony_ci int cmdCount = 0; 10942498b56bSopenharmony_ci OptEntry queryEntry = {' ', "", ControlCmd::CMD_QUERY, QueryLogHandler, false, 0}; 10952498b56bSopenharmony_ci OptEntry *cmdEntry = &queryEntry; // No cmd means CMD_QUERY cmd 10962498b56bSopenharmony_ci string cmdArgs = ""; 10972498b56bSopenharmony_ci while (1) { 10982498b56bSopenharmony_ci int choice = getopt_long(argc, argv, opts.c_str(), longOptions, &optIndex); 10992498b56bSopenharmony_ci if (choice == -1) { 11002498b56bSopenharmony_ci break; 11012498b56bSopenharmony_ci } 11022498b56bSopenharmony_ci if (choice == '?') { 11032498b56bSopenharmony_ci return RET_FAIL; 11042498b56bSopenharmony_ci } 11052498b56bSopenharmony_ci OptEntry *entry = GetOptEntry(choice); 11062498b56bSopenharmony_ci if (optind < argc && argv[optind][0] != '-') { // all options need only 1 argument 11072498b56bSopenharmony_ci PrintErr(ERR_TOO_MANY_ARGUMENTS); 11082498b56bSopenharmony_ci return ERR_TOO_MANY_ARGUMENTS; 11092498b56bSopenharmony_ci } 11102498b56bSopenharmony_ci if (entry->count == 0) { 11112498b56bSopenharmony_ci PrintErr(ERR_DUPLICATE_OPTION); 11122498b56bSopenharmony_ci return ERR_DUPLICATE_OPTION; 11132498b56bSopenharmony_ci } 11142498b56bSopenharmony_ci entry->count--; 11152498b56bSopenharmony_ci if (entry->cmd == ControlCmd::NOT_CMD) { 11162498b56bSopenharmony_ci int ret = entry->handler(context, optarg); 11172498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 11182498b56bSopenharmony_ci PrintErr(ret); 11192498b56bSopenharmony_ci return ret; 11202498b56bSopenharmony_ci } else { 11212498b56bSopenharmony_ci continue; 11222498b56bSopenharmony_ci } 11232498b56bSopenharmony_ci } 11242498b56bSopenharmony_ci cmdEntry = entry; 11252498b56bSopenharmony_ci cmdCount++; 11262498b56bSopenharmony_ci if (optarg != nullptr) { 11272498b56bSopenharmony_ci cmdArgs = optarg; 11282498b56bSopenharmony_ci } 11292498b56bSopenharmony_ci } 11302498b56bSopenharmony_ci if (cmdCount > 1) { 11312498b56bSopenharmony_ci cerr << ErrorCode2Str(ERR_COMMAND_INVALID) << endl; 11322498b56bSopenharmony_ci return ERR_COMMAND_INVALID; 11332498b56bSopenharmony_ci } 11342498b56bSopenharmony_ci // 2. Process CMD_XXX 11352498b56bSopenharmony_ci int ret = cmdEntry->handler(context, cmdArgs.c_str()); 11362498b56bSopenharmony_ci if (ret != RET_SUCCESS) { 11372498b56bSopenharmony_ci PrintErr(ret); 11382498b56bSopenharmony_ci return ret; 11392498b56bSopenharmony_ci } 11402498b56bSopenharmony_ci return RET_SUCCESS; 11412498b56bSopenharmony_ci} 11422498b56bSopenharmony_ci} // namespace HiviewDFX 11432498b56bSopenharmony_ci} // namespace OHOS 11442498b56bSopenharmony_ci 11452498b56bSopenharmony_ciint main(int argc, char* argv[]) 11462498b56bSopenharmony_ci{ 11472498b56bSopenharmony_ci (void)OHOS::HiviewDFX::HilogEntry(argc, argv); 11482498b56bSopenharmony_ci return 0; 11492498b56bSopenharmony_ci} 1150