一款简单好用的日志系统

此 log 移植自乐鑫esp32

源码如下:https://github.com/i-wanglei/EasyLog

此日志系统具有以下特点:

  • log输出等级可配置
  • 不同log等级可采用不同颜色输出
  • 使用简单
  • 格式通用,可打印log文件信息
  • 可支持时间戳输出

针对此 log 进行优化,可使用在嵌入式mcu平台,是一种不错的 log 输出方式
此 log 中包含一些关于 c 语言的一些冷门的重要知识,特再次作记录说明~!

源文件如下(为了方便说明,将文件集中在一个文件中):

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#define LOG_LOCAL_LEVEL         3

typedef 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

猜你喜欢

转载自blog.csdn.net/qq_43332314/article/details/126440167