好用的开源日志库:Easylogger解析与移植STM32
目录
一、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函数:

4.最终效果:

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)