1d96309c9Sopenharmony_ci/*
2d96309c9Sopenharmony_ci * Copyright (c) 2020 Huawei Device Co., Ltd.
3d96309c9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4d96309c9Sopenharmony_ci * you may not use this file except in compliance with the License.
5d96309c9Sopenharmony_ci * You may obtain a copy of the License at
6d96309c9Sopenharmony_ci *
7d96309c9Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8d96309c9Sopenharmony_ci *
9d96309c9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10d96309c9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11d96309c9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d96309c9Sopenharmony_ci * See the License for the specific language governing permissions and
13d96309c9Sopenharmony_ci * limitations under the License.
14d96309c9Sopenharmony_ci */
15d96309c9Sopenharmony_ci
16d96309c9Sopenharmony_ci#include "hilog_command.h"
17d96309c9Sopenharmony_ci
18d96309c9Sopenharmony_ci#include <securec.h>
19d96309c9Sopenharmony_ci#include <stdio.h>
20d96309c9Sopenharmony_ci#include <stdbool.h>
21d96309c9Sopenharmony_ci#include <string.h>
22d96309c9Sopenharmony_ci#include <stdlib.h>
23d96309c9Sopenharmony_ci#include <fcntl.h>
24d96309c9Sopenharmony_ci#include <unistd.h>
25d96309c9Sopenharmony_ci#include <getopt.h>
26d96309c9Sopenharmony_ci
27d96309c9Sopenharmony_ci#define OPTION_HELP 'h'
28d96309c9Sopenharmony_ci#define OPTION_LEVEL 'L'
29d96309c9Sopenharmony_ci#define OPTION_DOMAIN 'D'
30d96309c9Sopenharmony_ci#define OPTION_SILENCE 'S'
31d96309c9Sopenharmony_ci
32d96309c9Sopenharmony_ci#define PARA_AUTO "auto"
33d96309c9Sopenharmony_ci#define PARA_AUTO_LEN 4
34d96309c9Sopenharmony_ci
35d96309c9Sopenharmony_ci#define APPHILOGCAT_OFF 0
36d96309c9Sopenharmony_ci
37d96309c9Sopenharmony_ci#define HIVIEW_FEATURE_ON 1
38d96309c9Sopenharmony_ci#define HIVIEW_FEATURE_OFF 0
39d96309c9Sopenharmony_ci
40d96309c9Sopenharmony_ci#define HILOG_MODULE_MAX "FFFFF"
41d96309c9Sopenharmony_ci
42d96309c9Sopenharmony_cichar g_logLevelInfo[HILOG_LEVEL_MAX] = {
43d96309c9Sopenharmony_ci    'N', // "NONE"
44d96309c9Sopenharmony_ci    'N', // "NONE"
45d96309c9Sopenharmony_ci    'N', // "NONE"
46d96309c9Sopenharmony_ci    'D', // "DEBUG"
47d96309c9Sopenharmony_ci    'I', // "INFO"
48d96309c9Sopenharmony_ci    'W', // "WARN"
49d96309c9Sopenharmony_ci    'E', // "ERROR"
50d96309c9Sopenharmony_ci    'F'  // "FATAL"
51d96309c9Sopenharmony_ci};
52d96309c9Sopenharmony_ci
53d96309c9Sopenharmony_ciHiviewConfig g_hiviewConfig = {
54d96309c9Sopenharmony_ci    .outputOption = OUTPUT_OPTION_FLOW,
55d96309c9Sopenharmony_ci    .level = LOG_DEBUG,
56d96309c9Sopenharmony_ci    .logSwitch = HIVIEW_FEATURE_ON,
57d96309c9Sopenharmony_ci    .dumpSwitch = HIVIEW_FEATURE_OFF,
58d96309c9Sopenharmony_ci    .silenceMod = SILENT_MODE_OFF,
59d96309c9Sopenharmony_ci    .eventSwitch = HIVIEW_FEATURE_OFF,
60d96309c9Sopenharmony_ci    .logOutputModule = HILOG_MODULE_MAX,
61d96309c9Sopenharmony_ci};
62d96309c9Sopenharmony_ci
63d96309c9Sopenharmony_ciint HilogHelpProc(const char* tag)
64d96309c9Sopenharmony_ci{
65d96309c9Sopenharmony_ci    printf("Usage: %s [-h | --help] [-L <level> | --level=<level>] [--silence]\n", tag);
66d96309c9Sopenharmony_ci    printf("          [-D <domain> | --domain=<domain>]\n");
67d96309c9Sopenharmony_ci    printf("\n");
68d96309c9Sopenharmony_ci    printf("Options:\n");
69d96309c9Sopenharmony_ci    printf("-h, --help                         Help\n");
70d96309c9Sopenharmony_ci    printf("-L <level>, --level=<level>        Outputs logs at a specific level\n");
71d96309c9Sopenharmony_ci    printf("                                   Values of level :\n");
72d96309c9Sopenharmony_ci    printf("                                        D, stands for Debug\n");
73d96309c9Sopenharmony_ci    printf("                                        I, stands for Info\n");
74d96309c9Sopenharmony_ci    printf("                                        W, stands for Warning\n");
75d96309c9Sopenharmony_ci    printf("                                        E, stands for Error\n");
76d96309c9Sopenharmony_ci    printf("                                        F, stands for Fatal\n");
77d96309c9Sopenharmony_ci    printf("                                        auto, set log level with predefined macro\n");
78d96309c9Sopenharmony_ci    printf("-D <domain>, --domain=<domain>     Outputs logs at a specific domain\n");
79d96309c9Sopenharmony_ci    printf("--silence                          Silent mode, not output logs to the serial port\n");
80d96309c9Sopenharmony_ci    return -1;
81d96309c9Sopenharmony_ci}
82d96309c9Sopenharmony_ci
83d96309c9Sopenharmony_cibool SetLogLevel(unsigned char level)
84d96309c9Sopenharmony_ci{
85d96309c9Sopenharmony_ci    if (level >= LOG_DEBUG && level < HILOG_LEVEL_MAX) {
86d96309c9Sopenharmony_ci        g_hiviewConfig.level = level;
87d96309c9Sopenharmony_ci        printf("Set log level : %d \n", level);
88d96309c9Sopenharmony_ci        return true;
89d96309c9Sopenharmony_ci    }
90d96309c9Sopenharmony_ci    return false;
91d96309c9Sopenharmony_ci}
92d96309c9Sopenharmony_ci
93d96309c9Sopenharmony_ciint SetOutputDomain(const char *mod)
94d96309c9Sopenharmony_ci{
95d96309c9Sopenharmony_ci    if ((mod == NULL) || (strlen(mod) == 1)) {
96d96309c9Sopenharmony_ci        printf("Invalid command.\n");
97d96309c9Sopenharmony_ci        return -1;
98d96309c9Sopenharmony_ci    }
99d96309c9Sopenharmony_ci    int len = strlen(mod);
100d96309c9Sopenharmony_ci    int modSize = sizeof(g_hiviewConfig.logOutputModule);
101d96309c9Sopenharmony_ci
102d96309c9Sopenharmony_ci    (void)memset_s(g_hiviewConfig.logOutputModule, modSize, '0', modSize);
103d96309c9Sopenharmony_ci
104d96309c9Sopenharmony_ci    int destStart = ((DOMAIN_ID_LENGTH - len) > 0) ? (DOMAIN_ID_LENGTH - len) : 0;
105d96309c9Sopenharmony_ci    int sourceStart = ((len - DOMAIN_ID_LENGTH) > 0) ? (len - DOMAIN_ID_LENGTH) : 0;
106d96309c9Sopenharmony_ci    int copyLen = (len < DOMAIN_ID_LENGTH) ? len : DOMAIN_ID_LENGTH;
107d96309c9Sopenharmony_ci
108d96309c9Sopenharmony_ci    if (strncpy_s(g_hiviewConfig.logOutputModule + destStart, modSize - destStart, mod + sourceStart, copyLen) != 0) {
109d96309c9Sopenharmony_ci        printf("Copy log domain fail : %s \n", mod);
110d96309c9Sopenharmony_ci        return -1;
111d96309c9Sopenharmony_ci    }
112d96309c9Sopenharmony_ci
113d96309c9Sopenharmony_ci    printf("Set log domain : %s \n", g_hiviewConfig.logOutputModule);
114d96309c9Sopenharmony_ci    return 0;
115d96309c9Sopenharmony_ci}
116d96309c9Sopenharmony_ci
117d96309c9Sopenharmony_ciint SetOutputLevel(char cmd)
118d96309c9Sopenharmony_ci{
119d96309c9Sopenharmony_ci    unsigned char level = LOG_DEBUG;
120d96309c9Sopenharmony_ci    if (cmd == g_logLevelInfo[LOG_DEBUG]) {
121d96309c9Sopenharmony_ci        level = LOG_DEBUG;
122d96309c9Sopenharmony_ci    } else if (cmd == g_logLevelInfo[LOG_INFO]) {
123d96309c9Sopenharmony_ci        level = LOG_INFO;
124d96309c9Sopenharmony_ci    } else if (cmd == g_logLevelInfo[LOG_WARN]) {
125d96309c9Sopenharmony_ci        level = LOG_WARN;
126d96309c9Sopenharmony_ci    } else if (cmd == g_logLevelInfo[LOG_ERROR]) {
127d96309c9Sopenharmony_ci        level = LOG_ERROR;
128d96309c9Sopenharmony_ci    } else if (cmd == g_logLevelInfo[LOG_FATAL]) {
129d96309c9Sopenharmony_ci        level = LOG_FATAL;
130d96309c9Sopenharmony_ci    } else {
131d96309c9Sopenharmony_ci        printf("Invalid level : %c\n", cmd);
132d96309c9Sopenharmony_ci        return -1;
133d96309c9Sopenharmony_ci    }
134d96309c9Sopenharmony_ci
135d96309c9Sopenharmony_ci    if (SetLogLevel(level)) {
136d96309c9Sopenharmony_ci        printf("Set the log output level success.\n");
137d96309c9Sopenharmony_ci        return 0;
138d96309c9Sopenharmony_ci    }
139d96309c9Sopenharmony_ci    printf("Set the log output level failure level=%d.\n", level);
140d96309c9Sopenharmony_ci    return -1;
141d96309c9Sopenharmony_ci}
142d96309c9Sopenharmony_ci
143d96309c9Sopenharmony_ciint ProcAutoSet(void)
144d96309c9Sopenharmony_ci{
145d96309c9Sopenharmony_ci#ifdef OHOS_RELEASE
146d96309c9Sopenharmony_ci#if APPHILOGCAT_STATUS_RELEASE == APPHILOGCAT_OFF
147d96309c9Sopenharmony_ci    return -1;
148d96309c9Sopenharmony_ci#else
149d96309c9Sopenharmony_ci    SetLogLevel(CONFIG_LOG_LEVEL_RELEASE);
150d96309c9Sopenharmony_ci    printf("Default log level: %d \n", CONFIG_LOG_LEVEL_RELEASE);
151d96309c9Sopenharmony_ci#endif
152d96309c9Sopenharmony_ci#else  // OHOS_DEBUG
153d96309c9Sopenharmony_ci#if APPHILOGCAT_STATUS_DEBUG == APPHILOGCAT_OFF
154d96309c9Sopenharmony_ci    return -1;
155d96309c9Sopenharmony_ci#else
156d96309c9Sopenharmony_ci    SetLogLevel(CONFIG_LOG_LEVEL_DEBUG);
157d96309c9Sopenharmony_ci    printf("Default log level: %d \n", CONFIG_LOG_LEVEL_DEBUG);
158d96309c9Sopenharmony_ci#endif
159d96309c9Sopenharmony_ci#endif
160d96309c9Sopenharmony_ci    return 0;
161d96309c9Sopenharmony_ci}
162d96309c9Sopenharmony_ci
163d96309c9Sopenharmony_ciint HilogLevelProc(const char* arg)
164d96309c9Sopenharmony_ci{
165d96309c9Sopenharmony_ci    if (arg == NULL) {
166d96309c9Sopenharmony_ci        printf("Invalid command.\n");
167d96309c9Sopenharmony_ci        return -1;
168d96309c9Sopenharmony_ci    }
169d96309c9Sopenharmony_ci    if (strncmp(arg, PARA_AUTO, PARA_AUTO_LEN) == 0) {
170d96309c9Sopenharmony_ci        return ProcAutoSet();
171d96309c9Sopenharmony_ci    }
172d96309c9Sopenharmony_ci    char level = arg[0];
173d96309c9Sopenharmony_ci    return SetOutputLevel(level);
174d96309c9Sopenharmony_ci}
175d96309c9Sopenharmony_ci
176d96309c9Sopenharmony_ciint HilogDomainProc(const char* arg)
177d96309c9Sopenharmony_ci{
178d96309c9Sopenharmony_ci    return SetOutputDomain(arg);
179d96309c9Sopenharmony_ci}
180d96309c9Sopenharmony_ci
181d96309c9Sopenharmony_ciint HilogSilenceProc()
182d96309c9Sopenharmony_ci{
183d96309c9Sopenharmony_ci    g_hiviewConfig.silenceMod = SILENT_MODE_ON;
184d96309c9Sopenharmony_ci    return 0;
185d96309c9Sopenharmony_ci}
186d96309c9Sopenharmony_ci
187d96309c9Sopenharmony_ciint HilogCmdProc(const char *tag, int argc, char *argv[])
188d96309c9Sopenharmony_ci{
189d96309c9Sopenharmony_ci    int ret = -1;
190d96309c9Sopenharmony_ci    int optionIndex = 0;
191d96309c9Sopenharmony_ci    int opt = 0;
192d96309c9Sopenharmony_ci
193d96309c9Sopenharmony_ci    struct option longOptions[] = {
194d96309c9Sopenharmony_ci        {"help", no_argument, NULL, OPTION_HELP},
195d96309c9Sopenharmony_ci        {"level", required_argument, NULL, OPTION_LEVEL},
196d96309c9Sopenharmony_ci        {"domain", required_argument, NULL, OPTION_DOMAIN},
197d96309c9Sopenharmony_ci        {"silence", no_argument, NULL, OPTION_SILENCE},
198d96309c9Sopenharmony_ci        {0, 0, 0, 0}
199d96309c9Sopenharmony_ci    };
200d96309c9Sopenharmony_ci    const char *shortOptions = "hL:D:";
201d96309c9Sopenharmony_ci
202d96309c9Sopenharmony_ci    while ((opt = getopt_long(argc, argv, shortOptions, longOptions, &optionIndex)) != -1) {
203d96309c9Sopenharmony_ci        switch (opt) {
204d96309c9Sopenharmony_ci            case OPTION_HELP:
205d96309c9Sopenharmony_ci                ret = HilogHelpProc(tag);
206d96309c9Sopenharmony_ci                break;
207d96309c9Sopenharmony_ci            case OPTION_LEVEL:
208d96309c9Sopenharmony_ci                ret = HilogLevelProc(optarg);
209d96309c9Sopenharmony_ci                break;
210d96309c9Sopenharmony_ci            case OPTION_DOMAIN:
211d96309c9Sopenharmony_ci                ret = HilogDomainProc(optarg);
212d96309c9Sopenharmony_ci                break;
213d96309c9Sopenharmony_ci            case OPTION_SILENCE:
214d96309c9Sopenharmony_ci                ret = HilogSilenceProc();
215d96309c9Sopenharmony_ci                break;
216d96309c9Sopenharmony_ci            default:
217d96309c9Sopenharmony_ci                ret = -1;
218d96309c9Sopenharmony_ci                printf("Invalid command.\n");
219d96309c9Sopenharmony_ci                break;
220d96309c9Sopenharmony_ci        }
221d96309c9Sopenharmony_ci        if (ret == -1) {
222d96309c9Sopenharmony_ci            return -1;
223d96309c9Sopenharmony_ci        }
224d96309c9Sopenharmony_ci    }
225d96309c9Sopenharmony_ci    return ret;
226d96309c9Sopenharmony_ci}
227d96309c9Sopenharmony_ci
228d96309c9Sopenharmony_cibool FilterLevelLog(unsigned char setLevel, unsigned char logLevel)
229d96309c9Sopenharmony_ci{
230d96309c9Sopenharmony_ci    int logMinLevel;
231d96309c9Sopenharmony_ci
232d96309c9Sopenharmony_ci    for (logMinLevel = LOG_DEBUG; logMinLevel < HILOG_LEVEL_MAX; logMinLevel++) {
233d96309c9Sopenharmony_ci        if (logLevel == g_logLevelInfo[logMinLevel]) {
234d96309c9Sopenharmony_ci            break;
235d96309c9Sopenharmony_ci        }
236d96309c9Sopenharmony_ci    }
237d96309c9Sopenharmony_ci    // Loglevel >= set level, may print log
238d96309c9Sopenharmony_ci    if (logMinLevel >= setLevel) {
239d96309c9Sopenharmony_ci        return true;
240d96309c9Sopenharmony_ci    }
241d96309c9Sopenharmony_ci    return false;
242d96309c9Sopenharmony_ci}
243d96309c9Sopenharmony_ci
244d96309c9Sopenharmony_cibool FilterModuleLog(const char *setModule, const char *logModule)
245d96309c9Sopenharmony_ci{
246d96309c9Sopenharmony_ci    if (strncmp(setModule, HILOG_MODULE_MAX, DOMAIN_ID_LENGTH) == 0) {
247d96309c9Sopenharmony_ci        return true;
248d96309c9Sopenharmony_ci    }
249d96309c9Sopenharmony_ci    return strncmp(logModule, g_hiviewConfig.logOutputModule, DOMAIN_ID_LENGTH) == 0;
250d96309c9Sopenharmony_ci}