推荐一款开源嵌入式轻量级log框架

科技   2024-11-27 15:57   上海  

log.c简介

github链接:

https://github.com/rxi/log.c

MIT license

log.c是一个轻量级的日志库。一个用 C99 实现的简单日志库,这意味着它应该可以在任何支持 C99 标准的平台上编译和运行,如我们的嵌入式系统中。

特点:

  • 使用C99标准,适用于嵌入式。
  • 支持静默模式。
  • 支持日志级别设置。
  • 支持ANSI颜色编码。
  • 线程安全设计,允许设置锁机制。

使用示例

将 log.c 和 log.h 文件添加到项目即可。

log.c 提供了六个宏,对应不同的日志级别:

#include "log.h"

int main(void) 
{
    // 追踪日志
    log_trace("Trace message: %d"42);

    // 调试日志
    log_debug("Debug message: %s""This is a debug message");

    // 信息日志
    log_info("Info message: %s""This is an info message");

    // 警告日志
    log_warn("Warn message: %s""This is a warning message");

    // 错误日志
    log_error("Error message: %s""This is an error message");

    // 致命错误日志
    log_fatal("Fatal message: %s""This is a fatal message");

    return 0;
}

每个宏都接受一个 printf 风格的格式字符串和额外的参数。日志信息会被格式化并输出到 stderr

设置日志级别

我们可以使用 log_set_level 函数来设置日志级别,低于该级别的日志不会被输出到 stderr

log_set_level(LOG_ERROR); // 只输出错误和致命错误日志

输出到文件

我们可以使用 log_add_fp 函数,可以将日志输出到文件。

#include "log.h"

int main(void) 
{
    FILE* file = fopen("log.txt""w");
    if (file != NULL
    {
        log_add_fp(file, LOG_INFO); // 只输出信息级别以上的日志到文件
    }

    // 追踪日志
    log_trace("Trace message: %d"42);

    // 调试日志
    log_debug("Debug message: %s""This is a debug message");

    // 信息日志
    log_info("Info message: %s""This is an info message");

    // 警告日志
    log_warn("Warn message: %s""This is a warning message");

    // 错误日志
    log_error("Error message: %s""This is an error message");

    // 致命错误日志
    log_fatal("Fatal message: %s""This is a fatal message");

    return 0;
}

使用回调函数

我们可以注册一个回调函数来处理日志数据。如设置致命日志级别以上的日志打印按照我们的日志格式来处理,输出详细的日期:

#include "log.h"

static const char *s_level_strings[] = {
  "TRACE""DEBUG""INFO""WARN""ERROR""FATAL"
};

static void my_log_callback(log_Event *ev) 
{
  char buf[64];
  buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
  fprintf(
    ev->udata, "%s %-5s %s:%d: ",
    buf, s_level_strings[ev->level], ev->file, ev->line);
  vfprintf(ev->udata, ev->fmt, ev->ap);
  fprintf(ev->udata, "\n");
  fflush(ev->udata);
}

int main(void) 
{
    log_add_callback(my_log_callback, stderr, LOG_FATAL); // 只处理警告级别以上的日志

    // 追踪日志
    log_trace("Trace message: %d"42);

    // 调试日志
    log_debug("Debug message: %s""This is a debug message");

    // 信息日志
    log_info("Info message: %s""This is an info message");

    // 警告日志
    log_warn("Warn message: %s""This is a warning message");

    // 错误日志
    log_error("Error message: %s""This is an error message");

    // 致命错误日志
    log_fatal("Fatal message: %s""This is a fatal message");

    return 0;
}

多线程使用

如果在多线程环境中使用,可以使用 log_set_lock 来设置一个锁函数。

void lock_function(bool lock, void *udata) {
    if (lock) {
        // 获取锁
    } else {
        // 释放锁
    }
}

log_set_lock(lock_function, NULL);

使用颜色

如果我们希望日志输出带有颜色,可以在编译时定义 LOG_USE_COLOR。如:

gcc log.c test.c -DLOG_USE_COLOR


来自嵌入式大杂烩 嵌入式与Linux那些事公众号

Qt教程
致力于Qt教程,Qt技术交流,研发
 最新文章