1# Log Management 2 3## Overview 4 5### Function Introduction 6 7Basic functions of a log include recording key nodes and troubleshooting faults during the init startup process. 8- Logs help troubleshoot faults, check the startup duration of each subsystem, command execution duration, and more. 9- Log tags (including **param**, **uevent**, and **module**) for different modules can be viewed. 10- Logs can be printed for key phases, for example, the startup of the first phase, a required partition and its device node, **uevent** creation, service startup, and more. 11- Log levels are configurable. Available log levels include INIT_DEBUG, INIT_INFO, INIT_WARN, INIT_ERROR, and INIT_FATAL. 12 13### Basic Concepts 14 15The implementation of the init log function varies according to the OpenHarmony version. 16- OpenHarmony standard system: The init log function is implemented via **dmesg log** of the Linux kernel. 17- For the OpenHarmony LiteOS small system, the init log function is implemented by using the **hilog** API. 18- For the OpenHarmony LiteOS mini system, the init log function is implemented by using the **printf** API. 19 20### Log Type 21 init logs are classified into hilog and demsg logs. The hilog log records information related to system service processes, and the demsg log records information related to the kernel. 22### Log Level 23 init logs are classified into five levels, which can be set by the **(INIT_DEBUG_LEVEL)persist.init.debug.loglevel** parameter. 24 25 ``` 26 InitLogLevel: 27 INIT_DEBUG = 0, 28 INIT_INFO, 29 INIT_WARN, 30 INIT_ERROR, 31 INIT_FATAL 32 ``` 33 34 Kmsg log level. The options are as follows: 35 36 ``` 37 "<7>" =====> "DEBUG" 38 "<6>" =====> "INFO" 39 "<4>" =====> "WARNING" 40 "<3>" =====> "ERROR" 41 "<3>" =====> "FATAL" 42 ``` 43### Key Macros for Log Control 44 **INIT_DMESG** specifies whether to record kernel logs in **/dev/kmsg**. 45 **INIT_FILE** specifies whether to write log information to the **/data/init_agent/begetctl.log** file. 46 **INIT_AGENT** specifies whether to use hilog to record log information. 47 48 Key APIs: 49 ``` 50 void EnableInitLog (InitLogLevel level) Enables the init log function. 51 52 void SetInitLogLevel(InitLogLevel level) Sets the log level to control log output. 53 54 void StartupLog(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...) Provides an entry to the init log function. 55 ``` 56 **STARTUP_LOGI** is a macro defined for **StartupLog**, which is defined in the **/base/startup/init/interfaces/innerkits/include/beget_ext.h** file. Other logs are redefined based on the **STARTUP_LOGI** macro. 57 58 - deviceInfo module (init/device_info/idevice_info.h): 59 ``` 60 DINFO_LOGI 61 DINFO_LOGE 62 DINFO_LOGV 63 ``` 64 - Param JS API module (init/interfaces/kits/jskits/src/native_parameters_js.h): 65 ``` 66 PARAM_JS_LOGI 67 PARAM_JS_LOGE 68 PARAM_JS_LOGV 69 PARAM_JS_LOGW 70 ``` 71 - Shell module (init/services/begetctl/shell/shell_utils.h): 72 ``` 73 BSH_LOGI 74 BSH_LOGE 75 BSH_LOGV 76 ``` 77 - LoopEvent module (init/services/loopevent/utils/le_utils.h): 78 ``` 79 LE_LOGI 80 LE_LOGE 81 LE_LOGV 82 ``` 83 - Plug-in module (init/services/modules/plugin_adapter.h): 84 ``` 85 PLUGIN_LOGI 86 PLUGIN_LOGE 87 PLUGIN_LOGV 88 PLUGIN_LOGW 89 ``` 90 - Param module (init/services/param/include/param_utils.h): 91 ``` 92 PARAM_LOGI 93 PARAM_LOGE 94 PARAM_LOGV 95 PARAM_LOGW 96 ``` 97 - ParamWatcher module (init/services/param/watcher/include/watcher_utils.h): 98 ``` 99 WATCHER_LOGI 100 WATCHER_LOGE 101 WATCHER_LOGV 102 ``` 103 - init log module implemented based on the macros defined by **StartupLog** (init/services/log/init_log.h) 104 ``` 105 INIT_LOGV 106 INIT_LOGI 107 INIT_LOGW 108 INIT_LOGE 109 INIT_LOGF 110 ``` 111 112### Constraints 113N/A 114 115## How to Develop 116### Use Cases 117init logs are mainly used to start modules (like **param**, **ueventd**, and **module**) during init startup, and are used in the open API **begetutils**. 118 119### Available APIs 120 121**Table 1** Log APIs 122 | API| Format and Example| Description| 123 | -------- | -------- | -------- | 124 | INIT_LOGV | INIT_LOGV("Add %s to job %s", service->name, jobName); | Prints the log of the DEBUG level.| 125 | INIT_LOGI | INIT_LOGI("Start init first stage."); | Prints the log of the INFO level.| 126 | INIT_LOGW | INIT_LOGW("initialize signal handler failed"); | Prints the log of the WARN level.| 127 | INIT_LOGE | INIT_LOGE("Failed to format other opt"); | Prints the log of the ERROR level.| 128 | INIT_LOGF | INIT_LOGF("Failed to init system"); | Prints the log of the FATAL level.| 129 | INIT_ERROR_CHECK | INIT_ERROR_CHECK(ctx != NULL, return NULL, "Failed to get cmd args "); | Prints a log and executes **return NULL** when **ctx != NULL** is not true.| 130 | INIT_INFO_CHECK | INIT_INFO_CHECK(sockopt != NULL, return SERVICE_FAILURE, "Failed to malloc for service %s", service->name); | Prints a log and executes **return SERVICE_FAILURE** when **sockopt != NULL** is not true.| 131 | INIT_WARNING_CHECK | INIT_WARNING_CHECK(argsCount <= SPACES_CNT_IN_CMD_MAX, argsCount = SPACES_CNT_IN_CMD_MAX, "Too much arguments for command, max number is %d", SPACES_CNT_IN_CMD_MAX); | Prints a log and executes **argsCount = SPACES_CNT_IN_CMD_MAX** when **argsCount <= SPACES_CNT_IN_CMD_MAX** is not true.| 132 | INIT_CHECK | INIT_CHECK(arg != NULL, return NULL); | Executes **return NULL** when **arg != NULL** is not true.| 133 | INIT_CHECK_RETURN_VALUE | INIT_CHECK_RETURN_VALUE(errno == 0, -1); | Executes **return -1** when **errno == 0** is not true.| 134 | INIT_CHECK_ONLY_RETURN | INIT_CHECK_ONLY_RETURN(cmd != NULL); | Executes **return** when **cmd != NULL** is not true.| 135 | INIT_CHECK_ONLY_ELOG | INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0, "execv %s failed! err %d.", argv[0], errno); | Prints only **log "execv %s failed! err %d."** when **execv(argv[0], argv) == 0** is not true.| 136 137### Development Example 138 139 1. Call an API to print the log. 140 141 For example, call **INIT_LOGI("Start init first stage.")** in **//base/startup/init/services/init/standard/init.c** to print the log. 142 ```c 143 void SystemPrepare(void) 144 { 145 MountBasicFs(); 146 CreateDeviceNode(); 147 LogInit(); 148 // Make sure init log always output to /dev/kmsg. 149 EnableDevKmsg(); 150 INIT_LOGI("Start init first stage."); 151 // Only ohos normal system support 152 // two stages of init. 153 // If we are in updater mode, only one stage of init. 154 if (InUpdaterMode() == 0) { 155 StartInitSecondStage(); 156 } 157 } 158 ``` 159 Run **dmesg** to check the printed log **Start init first stage.** 160 161 2. Set the log level by running the **begetctl setloglevel level** command. 162 163 In the command, set **level** to one of the following log levels: **0** (**INIT_DEBUG**), **1** (**INIT_INFO**), **2** (**INIT_WARN**), **3** (**INIT_ERROR**), and **4** (**INIT_FATAL**). 164 165 After the setting is complete, the level set via **g_logLevel** of init takes effect immediately, and log APIs can print logs only when their log levels are higher than or equal to this level. For example, **begetctl setloglevel 3** sets the log level to **INIT_ERROR**. In this case, only **INIT_LOGE** and **INIT_LOGF** will print logs. 166 167 After the system is restarted, the configured log level will take effect after the **load_persist_params** command in the **init.cfg** file is executed. 168 169