Zephyr日志使用指南-运行时日志过滤
本文说明如何进行运行时日志消息过滤。
在Zephyr通过编译时过滤可以限制模块最小的过滤等级,但在最小等级之上的模块日志还是会输出。我们在调试时希望控制相关模块日志进行输出分析,不希望其它无关的日志都输出,这种情况下需要在运行时可以设置模块的日志过滤等级。需要注意的是运行时过滤的等级只能大于或者等于编译时指定的过滤等级。
代码控制过滤等级 链接到标题
运行时过滤提供了过滤日志更多的灵活性,让我们在代码里面可以根据触发条件对日志过滤等级进行修改,更方便调试。
控制运行时日志使用的接口都在头文件include/logging/log_ctrl.h中声明,设置过滤等级的函数为log_filter_set。示例代码logging_sample.c中logging_filter_test函数演示了如何使用log_filter_set进行过滤:
/* 获取source id的函数需要自己实现 */
static int16_t log_source_id_get(const char *name)
{
/* 使用log_source_name_get取出每个source的名称做对比,确认source的id */
for (int16_t i = 0; i < log_src_cnt_get(CONFIG_LOG_DOMAIN_ID); i++) {
if (strcmp(log_source_name_get(CONFIG_LOG_DOMAIN_ID, i), name)
== 0) {
return i;
}
}
return -1;
}
static int logging_filter_test(const struct shell *shell, size_t argc, char **argv)
{
uint32_t level = strtol(argv[1], NULL, 0);
uint32_t act_level = 0;
shell_print(shell, "Set filter level %d", level);
act_level = log_filter_set(NULL, /* 第一个参数为backend,如果为NULL表示对所有的backend都进行设置 */
0, /* 第二个参数为domain_id,目前不支持多dimain,直接给0 */
log_source_id_get(STRINGIFY(logging_sample)), /* 第三个参数为source_id,代表的是要设置那个模块的等级,这里我们要设置logging_sample */
level); /* 第四个参数为level,表示要设置的过滤等级 */
/* 返回的act_level为实际生效的level */
shell_print(shell, "Set filter level %d act is %d", level, act_level);
return 0;
}
log_filter_set的level参数可选如下,返回值为实际实际生效
#define LOG_LEVEL_NONE 0U
#define LOG_LEVEL_ERR 1U
#define LOG_LEVEL_WRN 2U
#define LOG_LEVEL_INF 3U
#define LOG_LEVEL_DBG 4U
log_filter_set的返回值为实际生效的等级,当level设置的等级低于编译时等级时,将按照编译时默认等级进行设置生效。
通过Shell命令控制日志系统 链接到标题
当启用zephyr shell命令时,可以通过shell的log命令进行日志过滤等级设置,后端设置,状态查看等。log支持的命令如下
uart:~$ log help
log - Commands for controlling logger
Subcommands:
backend :Logger backends commands.
disable :'log disable <module_0> .. <module_n>' disables logs in
specified modules (all if no modules specified).
enable :'log enable <level> <module_0> ... <module_n>' enables logs
up to given level in specified modules (all if no modules
specified).
go :Resume logging
halt :Halt logging
list_backends :Lists logger backends.
status :Logger status
mem :Logger memory usage
举例演示如下:
-
将simple模块的日志过滤等级设置为INFO:
log enable inf simple
-
将simple模块的日志过滤等级设置为DEBUG:
log enable dbg simple
-
关闭simple模块的日志:
log disable simple
-
查看日志系统内存使用情况:
log mem
-
查看日志各模块的过滤状态:
log status
显示如下
uart:~$ log status module_name | current | built-in ---------------------------------------------------------- esp_timer | inf | inf flash_esp32 | inf | dbg fs_nvs | inf | dbg gpio_esp32 | inf | inf i2c | inf | inf i2c_esp32 | inf | inf i2c_shell | inf | inf intc_esp32c3 | inf | inf log | inf | inf logging_sample | wrn | inf module_inst | inf | dbg module_inst.inst0 | inf | inf module_inst.inst1 | inf | inf module_inst.inst2 | inf | inf os | inf | inf shell.shell_uart | inf | inf shell_uart | inf | inf simple | inf | inf这里current表示为当前设置的过滤等级,build-in为编译时设置的过滤等级。过滤等级上current不能低于build-in。
-
中断所有后端日志输出:
log halt
-
恢复所有后端日志输出:
log resume
参考 链接到标题
https://docs.zephyrproject.org/latest/services/logging/index.html