使用(fmt,##args) 自定义日志

#define TEST_QUEUE_DEBUD

#ifdef TEST_QUEUE_DEBUD
    #define LOG(fmt,args...) printk(fmt,##args)
#else
    #define LOG(fmt,args...)
#endif

如上代码,在模块软件调试阶段,可以定义宏开关,等发布时,去掉即可。

这里涉及到可变参数的问题

下面举例来说明可变参数:

void test(int,...);   第一个参数来指明可变参数的个数,例如test(2,1,2)表示两个参数分别为1和2.

函数在设计时,需要包含stdarg.h头文件:

以下是可变参数的基本使用方式:

  • 定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。
  • 在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
  • 使用 int 参数和 va_start 宏来初始化 va_list 变量为一个参数列表。宏 va_start 是在 stdarg.h 头文件中定义的。
  • 使用 va_arg 宏和 va_list 变量来访问参数列表中的每个项。
  • 使用宏 va_end 来清理赋予 va_list 变量的内存   
#include <stdio.h>
#include <stdarg.h>

void test(int num ,...)
{
     int num;
     va_list valist;              //初始化列表
     va_start(valist, num);       //把数据压列表
     num = va_arg(valist, int);   //访问指定的数据
     va_end(valist);              //释放内存

}

从上面代码可以猜想到,可变参数的实现是基于malloc的,使用malloc来动态分配内存空间,根据一个指试器来找到对应的内容。最后还要释放内存(暴露了自己使用了malloc)。

 

debug.c:#include "debug.h" // 默认日志配置 log_level_t CURRENT_LOG_LEVEL = LOG_LEVEL_INFO; FILE* LOG_STREAM = NULL; void set_log_level(log_level_t level) { CURRENT_LOG_LEVEL = level; } void set_log_stream(FILE* stream) { LOG_STREAM = stream; }debug.h:#ifndef DEBUG_H #define DEBUG_H #include <stdio.h> #include <time.h> #include <errno.h> #include <string.h> // 日志级别 typedef enum { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR, LOG_LEVEL_CRITICAL } log_level_t; // 日志配置 extern log_level_t CURRENT_LOG_LEVEL; extern FILE* LOG_STREAM; // 设置日志级别 void set_log_level(log_level_t level); // 设置日志输出流 void set_log_stream(FILE* stream); // 基础日志宏 #define LOG(level, fmt, ...) do { \ if (level >= CURRENT_LOG_LEVEL) { \ time_t now = time(NULL); \ char timestr[20]; \ strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", localtime(&now)); \ fprintf(LOG_STREAM ? LOG_STREAM : stderr, "[%s] %-8s %s:%d %s(): " fmt "\n", \ timestr, \ level == LOG_LEVEL_DEBUG ? "DEBUG" : \ level == LOG_LEVEL_INFO ? "INFO" : \ level == LOG_LEVEL_WARNING ? "WARNING" : \ level == LOG_LEVEL_ERROR ? "ERROR" : "CRITICAL", \ __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ fflush(LOG_STREAM ? LOG_STREAM : stderr); \ } \ } while (0) // 各级别日志宏 #define LOG_DEBUG(fmt, ...) LOG(LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__) #define LOG_INFO(fmt, ...) LOG(LOG_LEVEL_INFO, fmt, ##__VA_ARGS__) #define LOG_WARNING(fmt, ...) LOG(LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__) #define LOG_ERROR(fmt, ...) LOG(LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__) #define LOG_CRITICAL(fmt, ...) LOG(LOG_LEVEL_CRITICAL, fmt, ##__VA_ARGS__) // 错误检查宏 #define CHECK(expr, msg) do { \ if (!(expr)) { \ LOG_ERROR("%s: %s (errno=%d)", msg, strerror(errno), errno); \ return -1; \ } \ } while (0) // 带返回值的错误检查 #define CHECK_RET(expr, msg, ret_val) do { \ if (!(expr)) { \ LOG_ERROR("%s: %s (errno=%d)", msg, strerror(errno), errno); \ return ret_val; \ } \ } while (0) #endif // DEBUG_H
最新发布
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值