嵌入式开发|一款简单好用的日志系统

此 log 移植自乐鑫esp32
源码如下:https://github.com/i-wanglei/EasyLog
此日志系统具有以下特点:
  • log输出等级可配置
  • 不同log等级可采用不同颜色输出
  • 使用简单
  • 格式通用,可打印log文件信息
  • 可支持时间戳输出
针对此 log 进行优化,可使用在嵌入式mcu平台,是一种不错的 log 输出方式
此 log 中包含一些关于 c 语言的一些冷门的重要知识,特再次作记录说明~!
源文件如下(为了方便说明,将文件集中在一个文件中):
#include #include #include #define LOG_LOCAL_LEVEL3typedef enum { LOG_NONE,/*!< No log output */ LOG_ERROR,/*!< Critical errors, software module can not recover on its own */ LOG_WARN,/*!< Error conditions from which recovery measures have been taken */ LOG_INFO,/*!< Information messages which describe normal flow of events */ LOG_DEBUG,/*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ LOG_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ } log_level_t; #define LOG_FORMAT(letter, format)#letter " (%d) %s: " format "\n" #define LOGE( tag, format, ... )if (LOG_LOCAL_LEVEL >= LOG_ERROR){ log_write(LOG_FORMAT(E, format),log_timestamp(), tag, ##__VA_ARGS__); } #define LOGW( tag, format, ... )if (LOG_LOCAL_LEVEL >= LOG_WARN){ log_write(LOG_FORMAT(W, format), log_timestamp(), tag, ##__VA_ARGS__); } #define LOGI( tag, format, ... )if (LOG_LOCAL_LEVEL >= LOG_INFO){ log_write(LOG_FORMAT(I, format),log_timestamp(), tag, ##__VA_ARGS__); } #define LOGD( tag, format, ... )if (LOG_LOCAL_LEVEL >= LOG_DEBUG){ log_write(LOG_FORMAT(D, format),log_timestamp(), tag, ##__VA_ARGS__); } #define LOGV( tag, format, ... )if (LOG_LOCAL_LEVEL >= LOG_VERBOSE) { log_write(LOG_FORMAT(V, format),log_timestamp(), tag, ##__VA_ARGS__); }unsigned int log_timestamp(void); void log_write(const char* format, ...) __attribute__ ((format (printf, 1, 2))); void log_write(const char *format, ...) { va_list arg; va_start(arg, format); vprintf(format, arg); va_end(arg); }unsigned int log_timestamp(void) { return 0; }int main() { int ret = 0; LOGE("test", "hello %d", ret); return 0; }

【嵌入式开发|一款简单好用的日志系统】执行结果如下:
嵌入式开发|一款简单好用的日志系统
文章图片

补充说明:
  1. 通过修改宏定义#define LOG_LOCAL_LEVEL 3可以实现的输出等级的调整,范围0 - 5
  2. void log_write(const char *format, ...)函数:
    a. 内部采用格式化输出,达到与printf的作用,此处不做深入讲解,理解为printf就行
  3. unsigned int log_timestamp(void) 函数:
    a. 可根据各自的平台,将事件戳作为返回值输出返回
  4. __attribute__ ((format (printf, 1, 2)))
    a. 用来作语法检查
    / 用法原型 // archetype:为按照那种风格进行校验,如printf/scanf等 // string-index:格式化format字符串所在的位置,如void test(testA, format,...),此时为2 // first-to-check:第一个可变参数的位置,如void test(testA, format,...),此时为3 __attribute__((format(archetype, string-index, first-to-check)))

    b. 详细内容可以参考:https://blog.csdn.net/u014630623/article/details/101107023
    c. pass:分析时,可以先将此部分注释
    void log_write(const char* format, ...); // __attribute__ ((format (printf, 1, 2)));

  5. #define LOG_FORMAT(letter, format) #letter " (%d) %s: " format "\n"
    a. #的作用是将letter转化为字符串
    b. 可以使用gcc main.c -E > debug查看预编译 LOGE("test", "hello %d", ret); 预编译结果为if (3 >= LOG_ERROR) { log_write("E" " (%d) %s: " "hello %d" "\n", log_timestamp(), "test"); };
    c. 有关#和##关键字的使用可以参考:https://blog.csdn.net/dotphoenix/article/details/4345174

    推荐阅读