一个用纯 C99 写的小型高效日志库,只有两个文件,不需要任何第三方依赖

 

大家好,最近在嵌入式项目里写日志总是东拼西凑,用的 printf、UART、串口,有时候还得自己实现一堆错误码映射,真是头大。直到我发现了一个小而强的库——log.c,用它一刀切解决了各种日志痛点。下面聊聊它到底是什么、能干嘛、怎么用,还有优缺点,绝对够实用。


什么是 log.c?
log.c 是一个用纯 C99 写的小型日志库,只有两个文件:log.c 和 log.h。把它丢到项目里去编译就能用,不需要任何第三方依赖。它提供了六种日志宏,能帮你快速打印带时间戳、文件名、行号和日志级别的日志。


解决了哪些痛点?

  • • 统一接口:不再用乱七八糟的 printf,把所有日志调用都换成统一的 log_info()、log_warn() 之类,维护更清爽。

  • • 多级别管理:从 TRACE 到 FATAL,六个级别随意开关,不用每次都加 ifdef。

  • • 多输出目标:串口、文件、回调都能往里加,甚至能给你一个回调接口把日志推到 RTOS 队列。

  • • 线程安全:自带锁函数接口,多线程环境也不会乱输出。

  • • 小巧易移植:源代码只有几十 KB,完全自己能看懂,随改随用。


安装 & 使用

  1. 1. 下载或直接把 log.c、log.h 拷到项目里。

  2. 2. 在 Makefile 或 IDE 里加入编译:

    SRCS += log.c
  • 3. 在入口函数初始化:

    #include "log.h"

    int main(void) {
        // 默认会打印到 stderr,嵌入式里可重定向到串口
        log_set_level(LOG_DEBUG); // 只输出 DEBUG 及以上
        log_info("系统初始化完成");
        // ...
        return 0;
    }
  • 4. (可选)添加文件输出或回调:

    FILE *fp = fopen("log.txt", "w");
    log_add_fp(fp, LOG_INFO); // INFO 以上写到文件
    // 回调示例:把日志推给自定义函数
    log_add_callback(my_log_callback, NULL, LOG_WARN);

  • 简易示例

    #include "log.h"

    intmain(void) {
        // 安静模式:不向 stderr 打印
        log_set_quiet(true);
        // 级别设为 WARN,低于 WARN 的都会被忽略
        log_set_level(LOG_WARN);

        // 常规日志
        log_debug("这条日志不会显示");
        log_warn("温度过高:%d°C", 85);
        log_error("传感器初始化失败");

        return0;
    }

    上面代码会在串口(或 stderr)输出类似:

    21:45:10 WARN main.c:10: 温度过高:85°C
    21:45:10 ERROR main.c:11: 传感器初始化失败

    核心 API 一览

    API

    功能

    备注

    log_trace/debug/info/warn/error/fatal

    日志宏,按级别打印

    打印到 stderr,嵌入式可重定向

    log_set_quiet(bool)

    安静模式

    只影响 stderr,文件和回调仍生效

    log_set_level(int)

    设置日志级别

    低于此级别的日志被忽略

    log_add_fp(FILE*, int)

    添加文件输出

    level 以上写入,失败返回 <0

    log_add_callback(fn, udata, level)

    注册回调

    可做网络转发、RTOS 队列

    log_set_lock(fn, udata)

    设置锁函数

    多线程/多核下保证线程安全

    log_level_string(int)

    级别字符串

    举例:"INFO"、"ERROR"

    支持编译时开色:

    gcc -DLOG_USE_COLOR ...

    就能在终端看到彩色输出。


    优缺点对比

    优点

    缺点

    轻量级,只有两个文件

    不支持异步写文件(但可自己回调实现)

    接口简单,几乎零学习成本

    时间戳用系统时间,需要你自己提供时间源

    多输出目标(stderr/文件/回调)

    不内置滚动日志或归档

    可配置锁,多线程安全

    只针对 C99,不适合更老编译器

    支持彩色输出,阅读体验佳

    日志格式固定,如要定制需修改源码


    总结
    要是在嵌入式里一直为日志烦心,或者想快速给项目加个“秒懂”级别的输出系统,那 log.c 绝对是首选。它小巧、易移植、功能够用,还能自己扩展任意回调。虽然不支持日志滚动和异步,但就地改改源码,或者用回调配合 RTOS 队列,完全能满足大部分需求。总之,够轻、够灵活、够方便,让你从此告别 printf 的手忙脚乱。

    项目地址:https://github.com/rxi/log.c

     

    发表评论