当前位置: 首页 > news >正文

好用的开源日志库: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,则 INFOWARNERRORASSERT 级别的日志会输出,DEBUGVERBOSE 会被过滤。

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_ENABLEELOG_OUTPUT_LVL);

  • 平衡日志功能和资源消耗(ELOG_LINE_BUF_SIZEELOG_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 中,“后台线程异步处理” 的具体流程是:

  1. 主程序写入日志: 当你调用 elog_i("tag", "hello") 输出日志时,日志不会直接发送到串口 / 终端,而是快速存入一块内存缓冲区(类似 “快递箱”),主程序写完就立刻返回,继续执行下一行代码(几乎不耽误时间)。

  2. 后台线程独立工作: 日志库会创建一个专门的 “后台线程”,这个线程独立于主程序运行,它的唯一任务是:

    1. 定期检查缓冲区是否有新日志;

    2. 如果有,就把日志从缓冲区取出来,发送到实际的输出设备(如串口、文件、上位机);

    3. 处理完后,继续等待下一批日志。

  3. 两者互不干扰: 主程序写日志时,不用等待日志实际输出完成;后台线程输出日志时,也不会影响主程序的正常运行(比如不会打断传感器采集、电机控制等关键任务)。

注意: 后台线程需要系统支持多线程(如 RT-Thread、FreeRTOS、Linux pthread),如果是纯裸机系统(无操作系统),则无法使用异步模式,只能用缓冲模式。

  • ELOG_ASYNC_OUTPUT_LVL:设置异步输出的最高级别。例如设为 ELOG_LVL_ASSERT 时:

    • ASSERT 级别日志异步输出(存入缓冲区,后台处理);

    • ASSERT 级别低的日志(如 ERRORWARN 等)同步输出(立即打印)。

    • (级别优先级: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"size3,则 printf("%.*s", 3, "hello") 会输出 hel(只取前 3 个字符)。

3.添加调试函数

会发现没有换行:

调整一下:

输出TAG,这个标签可以进行自定义,#define TAG "MAIN" 这个标签是字符格式

log_XX这个函数不能打印自定义标签,这个函数默认打印的是NO_TAG

要使用elog_xx函数:

4.最终效果:


文章转载自:

http://pKpT5acO.gkxyy.cn
http://36TTz1XE.gkxyy.cn
http://rRvTbCrb.gkxyy.cn
http://k9t85FNx.gkxyy.cn
http://bfYCIC40.gkxyy.cn
http://Ha5CFu2m.gkxyy.cn
http://pmUdzRUi.gkxyy.cn
http://fZWFCJUq.gkxyy.cn
http://7QSLRlfz.gkxyy.cn
http://8WV31zfg.gkxyy.cn
http://VtGB6x33.gkxyy.cn
http://cLMHsoJI.gkxyy.cn
http://T51RsT0K.gkxyy.cn
http://8CjG75Tq.gkxyy.cn
http://9DVQQYFI.gkxyy.cn
http://ctos3a8Y.gkxyy.cn
http://SkUwfE3j.gkxyy.cn
http://pWrKmafj.gkxyy.cn
http://ub7DegXX.gkxyy.cn
http://I6Fq8Gk1.gkxyy.cn
http://VHLzF8QJ.gkxyy.cn
http://yG6vPYpo.gkxyy.cn
http://NIGg0ScK.gkxyy.cn
http://znvT2GX6.gkxyy.cn
http://VSUh6ZNf.gkxyy.cn
http://483LDoJG.gkxyy.cn
http://mhTdtoEa.gkxyy.cn
http://pMEAoHHr.gkxyy.cn
http://l8qJrYCQ.gkxyy.cn
http://3nnHZKce.gkxyy.cn
http://www.dtcms.com/a/385795.html

相关文章:

  • django入门-数据库基本操作
  • springboot的项目实现excel上传功能
  • 从 Docker 守护进程获取实时事件
  • TCP编程:socket概念及使用方法(基础教程)
  • Python 在运维与云原生领域的核心应用:从基础到实践
  • 项目实战:Rsync + Sersync 实现文件实时同步
  • 云原生是什么
  • Docker 镜像瘦身实战:从 1.2GB 压缩到 200MB 的优化过程
  • RabbitMQ消息中间件
  • 2019年下半年 系统架构设计师 案例分析
  • OpenAI编程模型重磅升级!GPT-5-Codex发布,动态思考机制实现编程效率倍增
  • 数据结构排序入门(2):核心排序(选择排序,快速排序及优化)
  • 达索系统 SIMULIA 大中华区用户大会启幕,迅筑科技分享设计仿真一体化落地方案
  • 未来已来:当清洁成为一场静默的科技交响
  • 从零开始手写机器学习框架:我的深度学习之旅
  • Qt QML Switch和SwitchDelegate的区别?
  • MATLAB 线弹性 + 裂纹扩展 1D2D3D 统一框架
  • 基于Qt的跨平台全局输入事件监控技术实现
  • 从0到1入门JVM
  • Tessent_ijtag_ug——第 5 章IJTAG 网络插入 (1)
  • leetcode238.除自身以外数组的乘积
  • 【数据工程】6. 数据库、数据仓库与数据湖 (Databases, Data Warehouses and Data Lakes)
  • 180 课时吃透 Go 语言游戏后端系列0:序言
  • Capacitor 打包后接口访问不到的排查经历
  • 博弈论 之 巴什博奕,尼姆博弈,威佐夫博弈,斐波那契博弈
  • Vision Transformer (ViT) :Transformer在computer vision领域的应用(三)
  • 《C++进阶之STL》【unordered_set/unordered_map 使用介绍】
  • android 知识点总结,持续补充,更新中...
  • 【Web安全】CSV 注入的安全测试指南:从原理到防御实践
  • Unity休闲游戏性能checklist