日志的基本功能就是记录init启动中的关键节点,以及定位故障问题。
init日志根据OpenHarmony版本不同实现方式不同。
Init的日志记录主要分为hilog 和demsg, hilog主要记录系统业务流程相关的日志,demsg 记录内核相关的日志。
init 日志级别分为五级,可以通过设置(INIT_DEBUG_LEVEL)persist.init.debug.loglevel参数来控制
InitLogLevel:
INIT_DEBUG = 0,
INIT_INFO,
INIT_WARN,
INIT_ERROR,
INIT_FATAL
Kmsg 日志级别:
"<7>" =====> "DEBUG"
"<6>" =====> "INFO"
"<4>" =====> "WARNING"
"<3>" =====> "ERROR"
"<3>" =====> "FATAL"
INIT_DMESG 控制是否记录内核日志 /dev/kmsg INIT_FILE 控制是否将日志写入文件 /data/init_agent/begetctl.log INIT_AGENT 控制是否走Hilog记录日志
关键接口:
void EnableInitLog(InitLogLevel level) 使能log
void SetInitLogLevel(InitLogLevel level) 设置log 的级别,控制日志的输出
void StartupLog(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...) 是init log的入口
STARTUP_LOGI 是对StartupLog 定义的宏,在头文件/base/startup/init/interfaces/innerkits/include/beget_ext.h中定义,其他log都是基于STARTUP_LOGI这个宏重定义的:
DINFO_LOGI
DINFO_LOGE
DINFO_LOGV
PARAM_JS_LOGI
PARAM_JS_LOGE
PARAM_JS_LOGV
PARAM_JS_LOGW
BSH_LOGI
BSH_LOGE
BSH_LOGV
LE_LOGI
LE_LOGE
LE_LOGV
PLUGIN_LOGI
PLUGIN_LOGE
PLUGIN_LOGV
PLUGIN_LOGW
PARAM_LOGI
PARAM_LOGE
PARAM_LOGV
PARAM_LOGW
WATCHER_LOGI
WATCHER_LOGE
WATCHER_LOGV
INIT_LOGV
INIT_LOGI
INIT_LOGW
INIT_LOGE
INIT_LOGF
无
init log主要应用在init的启动过程中,启动相关模块(param、ueventd、module等)中,以及对外提供的begetutils接口中。
表1 log接口说明
接口 | 接口格式和示例 | 说明 |
---|---|---|
INIT_LOGV | INIT_LOGV("Add %s to job %s", service->name, jobName); | 输出debug log。 |
INIT_LOGI | INIT_LOGI("Start init first stage."); | 输出info log。 |
INIT_LOGW | INIT_LOGW("initialize signal handler failed"); | 输出warning log。 |
INIT_LOGE | INIT_LOGE("Failed to format other opt"); | 输出err log。 |
INIT_LOGF | INIT_LOGF("Failed to init system"); | 输出fatal log。 |
INIT_ERROR_CHECK | INIT_ERROR_CHECK(ctx != NULL, return NULL, "Failed to get cmd args "); | 判断 ctx != NULL 不成立的情况下输出log,同时执行 return NULL。 |
INIT_INFO_CHECK | INIT_INFO_CHECK(sockopt != NULL, return SERVICE_FAILURE, "Failed to malloc for service %s", service->name); | 判断 sockopt != NULL 不成立的情况下输出log,同时执行 return SERVICE_FAILURE。 |
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); | 判断 argsCount <= SPACES_CNT_IN_CMD_MAX 不成立的情况下输出log,同时执行 argsCount = SPACES_CNT_IN_CMD_MAX。 |
INIT_CHECK | INIT_CHECK(arg != NULL, return NULL); | 判断arg != NULL 不成立的情况下执行 return NULL。 |
INIT_CHECK_RETURN_VALUE | INIT_CHECK_RETURN_VALUE(errno == 0, -1); | 判断errno == 0 不成立的情况下执行 return -1。 |
INIT_CHECK_ONLY_RETURN | INIT_CHECK_ONLY_RETURN(cmd != NULL); | 判断cmd != NULL 不成立的情况下执行 return。 |
INIT_CHECK_ONLY_ELOG | INIT_CHECK_ONLY_ELOG(execv(argv[0], argv) == 0, "execv %s failed! err %d.", argv[0], errno); | 判断execv(argv[0], argv) == 0 不成立的情况下只打印log "execv %s failed! err %d."。 |
调用接口打印日志
例如在 //base/startup/init/services/init/standard/init.c中调用接口INIT_LOGI("Start init first stage.")打印日志。
void SystemPrepare(void)
{
MountBasicFs();
CreateDeviceNode();
LogInit();
// Make sure init log always output to /dev/kmsg.
EnableDevKmsg();
INIT_LOGI("Start init first stage.");
// Only ohos normal system support
// two stages of init.
// If we are in updater mode, only one stage of init.
if (InUpdaterMode() == 0) {
StartInitSecondStage();
}
}
通过dmesg可以查看打印的log,"Start init first stage."。
通过命令设置日志等级
通过命令begetctl setloglevel level,其中level对应log的等级0~4,即INIT_DEBUG,INIT_INFO,INIT_WARN,INIT_ERROR,INIT_FATAL。
设置完成之后init的g_logLevel等级立即生效,上述log接口中log等级大于等于g_logLevel才会打印日志。例如:begetctl setloglevel 3,即设置log等级为INIT_ERROR,则上述的log接口中只有INIT_LOGE、INIT_LOGF才会打印log。
系统重启之后在init.cfg中"load_persist_params "命令之后生效设置的log等级。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。