ulog 日志简介

ulog 是一个非常简洁、易用的 C/C++ 日志组件,第一个字母 u 代表 μ,即微型的意思。它能做到最低ROM<1K, RAM<0.2K的资源占用。ulog 不仅有小巧体积,同样也有非常全面的功能,其设计理念参考的是另外一款 C/C++ 开源日志库:EasyLogger(简称 elog),并在功能和性能等方面做了非常多的改进。主要特性如下:

  • 日志输出的后端多样化,可支持例如:串口、网络,文件、闪存等后端形式。
  • 日志输出被设计为线程安全的方式,并支持异步输出模式。
  • 日志系统高可靠,在中断 ISR 、Hardfault 等复杂环境下依旧可用。
  • 日志支持运行期 / 编译期设置输出级别。
  • 日志内容支持按关键词及标签方式进行全局过滤。
  • API 和日志格式可兼容 linux syslog。
  • 支持以 hex 格式 dump 调试数据到日志中。
  • 兼容 rtdbg (RTT 早期的日志头文件)及 EasyLogger 的日志输出 API。

ulog 架构

下图为 ulog 日志组件架构图:

ulog 框架

  • 前端:该层作为离应用最近的一层,给用户提供了 syslog 及 LOG_X 两类 API 接口,方便用户在不同的场景中使用。
  • 核心:中间核心层的主要工作是将上层传递过来的日志,按照不同的配置要求进行格式化与过滤然后生成日志帧,最终通过不同的输出模块,输出到最底层的后端设备上。
  • 后端:接收到核心层发来的日志帧后,将日志输出到已经注册的日志后端设备上,例如:文件、控制台、日志服务器等等。

更为详细的ulog日志介绍可参考官方文档https://www.rt-thread.org/document/site/programming-manual/ulog/ulog/,本文我们需要添加 ulog日志,并配置日志输出到串口方便查看。配置方法如下:

 

 

  1. 在工程目录下打开 env 工具,输入menuconfig命令配置工程
  2. RT-Thread Components → Utilities 下使能Enable ulog菜单,然后会展开ulog的配置选项,这些选项的详细说明可参考官方文档,这里不作赘述;我们这里设置静态日志级别为Debug这样所有级别的日志都可输出;使能ISR log以便可以在中断中使用ulog;配置一条日志的最大长度为256;使能使能运行时的日志过滤器,以便在系统运行时按照标签、关键字等方式对日志进行动态过滤;使能异步日志输出模式,这样日志内容先写入缓冲区然后由专门的日志输出线程进行输出;使能控制台作为后端,日志可以输出到控制台串口上;这里不使用linux syslog格式,若需要与linux应用兼容可打开,syslog格式的输出无颜色。配置如图所示:
  3. 使能ulog后可对其记录格式进行配置,在RT-Thread Components → Utilities →log format菜单中,这里我们使能浮点数和颜色的支持,记录时间信息、时间戳、日志级别、日志标签、线程信息,注意打开浮点数支持时会占用更多的线程栈空间并且会使能编译器自带的libc库。配置如图所示:
  4. 由于使能了记录日志时间戳信息,所以需要打开rtc,在 RT-Thread Components → Device Drivers中选中Using RTC device driversUsing software simulation RTC device,这里使用软件模拟RTC时间,在无硬件RTC的设备上也可正确运行,但是重启后时间需重新设置。配置如图所示:
  5. 以上配置完成了所需宏定义的配置(在rtconfig.h中),然后退出并保存menuconfig配置,输入scons --target=mdk4/mdk5/iar 命令根据所选用的编译器重新生成工程,ulog所需的驱动文件便添加进了工程中。

 ulog 测试

完成上述配置后便可以在工程中使用ulog日志了,使用时首先要在源文件开头定义本源文件所需的日志标签和级别,然后再包含ulog.h,这样每个源文件可以有不同的标签和级别,便于区分:

#define LOG_TAG     "example"     // 该模块对应的标签。不定义时,默认:NO_TAG
#define LOG_LVL     LOG_LVL_DBG   // 该模块对应的日志输出级别。不定义时,默认:调试级别
#include <ulog.h>                 // 必须在 LOG_TAG 与 LOG_LVL 下面

然后添加一个MSH命令测试ulog日志:

/* ulog测试 */
static int __ulog_test(int argc,char **argv)
{
  static int count=0;
  static uint8_t buf[128];
  int i=0;
  
  for(i=0;i<sizeof(buf);i++)
  {
    buf[i]=i+count;
  }
  
  /* output different level log by LOG_X API */
  LOG_D("LOG_D(%d): RT-Thread is an open source IoT operating system from China.", count);
  LOG_I("LOG_I(%d): RT-Thread is an open source IoT operating system from China.", count);
  LOG_W("LOG_W(%d): RT-Thread is an open source IoT operating system from China.", count);
  LOG_E("LOG_E(%d): RT-Thread is an open source IoT operating system from China.", count);
  LOG_RAW("LOG_RAW(%d): RT-Thread is an open source IoT operating system from China.", count);
  ulog_hexdump("buf_dump_test",16,buf,sizeof(buf));
  
  count++;
  
  return 0;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT_ALIAS(__ulog_test,ulogtest, ulog test.);

系统启动后在终端输入ulogtest命令测试ulog日志的输出,默认后端设备为控制台,也可以实现并注册自己的后台,如文件等,可参照console_be.c中的实现方法。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐