好用的开源日志库:Easylogger解析与移植STM32
目录
一、Easylogger的相关文件解析
1.日志输出总开关
2.静态日志输出级别
3. 断言检查开关
4.单条日志的缓冲区大小
5.行号输出的最大长度
6.过滤标签的最大长度
7.过滤关键字的最大长度
8.标签级别过滤的最大数量
9.换行符定义
总结
1.日志颜色配置(终端彩色输出)
2.日志格式配置(附加信息开关)
3.异步输出模式配置(非阻塞日志)
详细解析一下异步输出的处理逻辑:
4. 缓冲输出模式配置(批量打印)
二、移植Easylogger
一、Easylogger的相关文件解析
这些代码是 Easylogger(一款轻量级嵌入式日志库)的核心配置项(位于 elog_cfg.h
中),用于控制日志库的功能开关、输出级别、缓冲区大小等关键特性。下面逐一解释每个配置的作用:
1.日志输出总开关
#define ELOG_OUTPUT_ENABLE
-
作用:定义此宏时,日志库会开启输出功能(日志能正常打印);如果注释掉(
// #define ELOG_OUTPUT_ENABLE
),所有日志输出会被禁用(节省资源,适合发布版本)。 -
场景:调试阶段保留,正式发布时可注释以关闭所有日志。
2.静态日志输出级别
#define ELOG_OUTPUT_LVL ELOG_LVL_VERBOSE
-
作用:设置全局日志输出的最低级别,只有级别大于等于此值的日志才会被打印。
-
日志级别范围(从低到高,优先级递增):
-
ELOG_LVL_ASSERT
:断言错误(最高优先级,通常用于致命错误) -
ELOG_LVL_ERROR
:错误(如功能失败) -
ELOG_LVL_WARN
:警告(如不影响运行但需注意的情况) -
ELOG_LVL_INFO
:信息(如正常流程节点) -
ELOG_LVL_DEBUG
:调试(如变量值、函数调用) -
ELOG_LVL_VERBOSE
:详细信息(最冗余,如每步操作的细节)
-
-
示例:若设为
ELOG_LVL_INFO
,则INFO
、WARN
、ERROR
、ASSERT
级别的日志会输出,DEBUG
和VERBOSE
会被过滤。
3. 断言检查开关
#define ELOG_ASSERT_ENABLE
-
作用:定义此宏时,日志库会启用
elog_assert()
断言功能(类似 C 标准库的assert()
),当断言条件不满足时,会打印断言日志并触发错误处理(如程序终止)。 -
场景:调试阶段用于检查关键条件(如指针不为空、参数合法),发布版本可注释以关闭断言(减少资源消耗)。
4.单条日志的缓冲区大小
#define ELOG_LINE_BUF_SIZE 1024
-
作用:设置每条日志在内存中临时存储的缓冲区大小(单位:字节)。
-
注意:
-
若单条日志内容过长(超过此值),会被截断(只保留前 1024 字节)。
-
数值越大,单条日志可容纳的内容越多,但会消耗更多 RAM(嵌入式系统需权衡)
-
5.行号输出的最大长度
#define ELOG_LINE_NUM_MAX_LEN 5
-
作用:限制日志中输出的 “代码行号” 的最大字符长度(默认 5 位)。
-
示例:若代码行号是
12345
,会完整输出;若行号是123456
(6 位),会被截断为23456
(只保留最后 5 位)。 -
目的:控制日志格式的整齐性,避免行号过长导致日志排版混乱。
6.过滤标签的最大长度
#define ELOG_FILTER_TAG_MAX_LEN 30
-
作用:Easylogger 支持按 “标签(tag)” 过滤日志(如
elog_i("uart", "recv data")
中的"uart"
是标签),此配置限制标签的最大字符长度(30 字节)。 -
注意:超过长度的标签会被截断,确保过滤功能正常工作。
7.过滤关键字的最大长度
#define ELOG_FILTER_KW_MAX_LEN 16
-
作用:支持按 “关键字(keyword)” 过滤日志(如只输出包含
"error"
的日志),此配置限制关键字的最大长度(16 字节)。
8.标签级别过滤的最大数量
#define ELOG_FILTER_TAG_LVL_MAX_NUM 5
-
作用:Easylogger 支持为不同标签设置独立的日志级别(如
uart
标签只输出ERROR
及以上,i2c
标签输出DEBUG
及以上),此配置限制这种 “标签 - 级别” 映射的最大数量(最多 5 组)。 -
场景:当需要对多个模块(标签)设置不同日志级别时,若超过 5 组,需增大此值。
9.换行符定义
#define ELOG_NEWLINE_SIGN "\n"
-
作用:定义日志结尾的换行符号。
-
说明:
-
大多数系统用
"\n"
(换行); -
部分 Windows 环境可能需要
"\r\n"
(回车 + 换行),可在此修改。
-
总结
这些配置项是 Easylogger 的 “总开关” 和 “参数调节器”,核心作用是:
-
控制日志是否输出、输出哪些级别的日志(
ELOG_OUTPUT_ENABLE
、ELOG_OUTPUT_LVL
); -
平衡日志功能和资源消耗(
ELOG_LINE_BUF_SIZE
、ELOG_ASSERT_ENABLE
); -
适配不同场景的日志格式和过滤需求(标签长度、换行符等)。
实际使用时,可根据嵌入式系统的 RAM/ROM 资源、调试需求灵活调整(例如:调试阶段开全量日志,发布阶段关闭输出或只保留错误级别)。
还有一些 Easylogger 库中与日志样式、输出格式、异步 / 缓冲模式相关的高级设置
1.日志颜色配置(终端彩色输出)
#define ELOG_COLOR_ENABLE
#define ELOG_COLOR_ASSERT (F_MAGENTA B_NULL S_NORMAL)
#define ELOG_COLOR_ERROR (F_RED B_NULL S_NORMAL)
#define ELOG_COLOR_WARN (F_YELLOW B_NULL S_NORMAL)
#define ELOG_COLOR_INFO (F_CYAN B_NULL S_NORMAL)
#define ELOG_COLOR_DEBUG (F_GREEN B_NULL S_NORMAL)
#define ELOG_COLOR_VERBOSE (F_BLUE B_NULL S_NORMAL)
-
ELOG_COLOR_ENABLE
:开启日志彩色输出(仅在支持 ANSI 颜色码的终端有效,如 Linux 终端、VS Code 终端等)。注释此宏则关闭彩色,所有日志为默认颜色。 -
颜色宏的含义(以
F_MAGENTA B_NULL S_NORMAL
为例):-
F_XXX
:前景色(文字颜色),如F_RED
(红色)、F_GREEN
(绿色)。 -
B_XXX
:背景色,B_NULL
表示无背景色(默认)。 -
S_XXX
:文字样式,S_NORMAL
表示正常,S_BOLD
表示加粗(部分库支持)。
-
-
作用:通过颜色区分不同级别日志,直观识别重要信息(如错误用红色,警告用黄色)。
2.日志格式配置(附加信息开关)
#define ELOG_FMT_USING_FUNC
#define ELOG_FMT_USING_DIR
#define ELOG_FMT_USING_LINE
这些宏控制日志中是否包含额外调试信息,默认会拼接在日志内容前,格式类似: [时间] [级别] [标签] [文件路径:行号@函数名] 日志内容
-
ELOG_FMT_USING_FUNC
:启用则输出函数名(如main@
),方便定位日志所在函数。 -
ELOG_FMT_USING_DIR
:启用则输出文件路径(如src/main.c
),方便定位日志所在文件。 -
ELOG_FMT_USING_LINE
:启用则输出代码行号(如123
),配合文件路径快速找到代码位置。 -
使用建议:调试阶段全开启,发布阶段可注释(减少日志长度,节省带宽 / 存储)。
3.异步输出模式配置(非阻塞日志)
#define ELOG_ASYNC_OUTPUT_ENABLE
#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_ASSERT
#define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10)
#define ELOG_ASYNC_LINE_OUTPUT
#define ELOG_ASYNC_OUTPUT_USING_PTHREAD
-
ELOG_ASYNC_OUTPUT_ENABLE
:开启异步输出模式。此时日志不会立即打印,而是先存入缓冲区,由后台线程异步处理(避免日志打印阻塞主程序)。
详细解析一下异步输出的处理逻辑:
“后台线程异步处理” 是一种让日志打印不干扰主程序运行的技术,核心是 “让日志输出工作在‘后台’偷偷完成,主程序不用等待它结束”。
在 Easylogger 中,“后台线程异步处理” 的具体流程是:
-
主程序写入日志: 当你调用
elog_i("tag", "hello")
输出日志时,日志不会直接发送到串口 / 终端,而是快速存入一块内存缓冲区(类似 “快递箱”),主程序写完就立刻返回,继续执行下一行代码(几乎不耽误时间)。 -
后台线程独立工作: 日志库会创建一个专门的 “后台线程”,这个线程独立于主程序运行,它的唯一任务是:
-
定期检查缓冲区是否有新日志;
-
如果有,就把日志从缓冲区取出来,发送到实际的输出设备(如串口、文件、上位机);
-
处理完后,继续等待下一批日志。
-
-
两者互不干扰: 主程序写日志时,不用等待日志实际输出完成;后台线程输出日志时,也不会影响主程序的正常运行(比如不会打断传感器采集、电机控制等关键任务)。
注意: 后台线程需要系统支持多线程(如 RT-Thread、FreeRTOS、Linux pthread),如果是纯裸机系统(无操作系统),则无法使用异步模式,只能用缓冲模式。
-
ELOG_ASYNC_OUTPUT_LVL
:设置异步输出的最高级别。例如设为ELOG_LVL_ASSERT
时:-
ASSERT
级别日志异步输出(存入缓冲区,后台处理); -
比
ASSERT
级别低的日志(如ERROR
、WARN
等)同步输出(立即打印)。 -
(级别优先级:
ASSERT
>ERROR
>WARN
> ... >VERBOSE
)
-
-
ELOG_ASYNC_OUTPUT_BUF_SIZE
:异步缓冲区大小(默认 10 倍单行缓冲区),用于暂存异步日志。若日志产生过快填满缓冲区,新日志可能被丢弃(需根据系统吞吐量调整)。 -
ELOG_ASYNC_LINE_OUTPUT
:强制异步日志必须以换行符结尾,确保后台线程按行解析输出(避免日志内容错乱)。 -
ELOG_ASYNC_OUTPUT_USING_PTHREAD
:指定异步模式使用 POSIX 线程库(pthread
)实现后台线程(适用于 Linux、RT-Thread 等支持 pthread 的系统)。
4. 缓冲输出模式配置(批量打印)
#define ELOG_BUF_OUTPUT_ENABLE
#define ELOG_BUF_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10)
-
ELOG_BUF_OUTPUT_ENABLE
:开启缓冲输出模式。日志会先存入缓冲区,当缓冲区满或手动触发时,批量输出到目标设备(如串口、文件)。 -
ELOG_BUF_OUTPUT_BUF_SIZE
:缓冲区大小(默认 10 倍单行缓冲区),用于暂存待批量输出的日志。 -
与异步模式的区别:
-
缓冲模式:无后台线程,由主程序在合适时机(如缓冲区满)主动批量输出,仍可能阻塞但次数减少。
-
异步模式:由后台线程处理输出,主程序完全非阻塞(但依赖线程支持)。
-
-
适用场景:资源受限的嵌入式系统(无线程支持时),通过批量输出减少 IO 操作次数(如串口打印较耗时,批量输出更高效)。
二、移植Easylogger
1.使用cubemx配置一个初始化串口的工程(这里我们使用串口进行输出)
首先选择好对应的芯片型号,然后配置sys:
使用晶振做时钟源:
配置串口,默认配置就行:
时钟树配置,频率最大即可:
生成.c和.h文件:
最后直接生成工程。
2.移植代码
新建一个Middlewares的文件夹,将easylogger的源码复制进去
添加组以及相关文件:
添加头文件路径
此时有一个报错
注释这两个宏定义即可
对串口进行重定义(记得开启微库),并对elog_port.c进行重写:
%s
:表示输出字符串。
.*
:是一个特殊的长度控制符,用于指定字符串的输出长度。其中 *
会从后续参数中获取长度值(这里就是 size
)。
例如: 如果 log
是 "hello"
,size
是 3
,则 printf("%.*s", 3, "hello")
会输出 hel
(只取前 3 个字符)。
3.添加调试函数
会发现没有换行:
调整一下:
输出TAG,这个标签可以进行自定义,#define TAG "MAIN" 这个标签是字符格式
log_XX这个函数不能打印自定义标签,这个函数默认打印的是NO_TAG
要使用elog_xx函数: