uLog:一个专为资源受限的嵌入式设备设计的超轻量级结构化日志库

uLog 是一个专为资源受限的嵌入式设备设计的超轻量级结构化日志库。它借鉴了 Log4c、Log4j 的思路,但把负担甩得干干净净:一个 .h、一个 .c,只要有 stdio.h、string.h、stdarg.h,就能跑起来。最妙的是,完全可控、不用时啥都不占地方——编译时如果没定义 ULOG_ENABLED,根本就不生成任何日志代码,真·零开销。

适用场景与痛点
你是不是也遇到过这样的烦恼?

  • • 嵌入式项目没法用那些大而全的日志库,烧录空间和 RAM 动辄吃不消;

  • • 想分级输出(ERROR、INFO、DEBUG)却又不想把 printf 全局打开;

  • • 想把日志丢到串口、丢到 SD 卡、丢到内存环形缓冲,一套又一套,折磨人……

uLog 就是来救场的。它让你:“唰”一下搞定各种输出源,随时调节每个输出的阈值级别,开发/发布一键切换,省心又省资源。


主要特性

  • • 纯 C 实现,一个头文件+一个源文件,没人依赖;

  • • 支持 CRITICAL、ERROR、WARNING、INFO、DEBUG、TRACE 六档级别;

  • • 多路输出(console、文件、内存 buffer……)各自独立阈值;

  • • 编译期开关:ULOG_ENABLED 未定义时,无日志代码;

  • • 自带测试用例,质量在线,放心用。

特性

说明

一键开关

编译时 undef ULOG_ENABLED → 全部日志瞬间消失

多订阅机制

ULOG_SUBSCRIBE

 增加输出函数,ULOG_UNSUBSCRIBE 移除

级别可调

不同输出可设不同阈值,灵活控制信息量

零依赖

只要标准库,无额外包,适合各种裸机或 RTOS 环境

Python 示例
虽说 uLog 本身是 C 库,但很多时候你会把日志刷到文件或串口,然后用 Python 快速搞定后续处理。下面这段小脚本,示范了怎么把日志文件里所有 ERROR、CRITICAL 级别的行过滤出来:

import re

LOG_PATTERN = re.compile(r'(.+?) \[(.+?)\]: (.+)')

def parse_log_line(line):
    m = LOG_PATTERN.match(line)
    if not m:
        return None
    timestamp, level, msg = m.groups()
    return {'time': timestamp,'level': level,'msg': msg}

def filter_errors(logfile):
    with open(logfile,'r')as f:
    for line in f:
         entry = parse_log_line(line)
            if entry and entry['level']in('ERROR','CRITICAL'):
                  print(f"{entry['time']} - {entry['level']} - {entry['msg']}")

if __name__ =='__main__':
    filter_errors('device.log')

这段代码很简单:正则切分三段,把高危级别的直接打印出来,拿去做报警或统计都行。

优缺点一览

优点

缺点

极低的资源占用(代码+数据)

不支持异步输出(不过可以自己封装环形缓冲)

灵活的多路订阅/阈值控制

没有原生网络传输,需要自己实现 send/recv

编译期开关无痕息化

纯 C 实现,对 C++ 用户需要加 extern "C"

测试覆盖,社区维护

不带 GUI,不带高级插件,定位更偏底层

总结
总的来说,uLog 干净、轻量、高度可定制,特别适合那些对资源敏感又想要分级日志和多路输出的嵌入式项目。要用就用最简单的那一套,不要再把一大堆 logging 框架搬到 MC 平台上折腾了,轻装上阵,效率翻倍!

项目地址:https/github.com/rdpoor/ulog

发表评论