为什么使用宏定义日志接口?

11 篇文章 0 订阅

频繁调用的情况下,宏定义日志接口是一种编程技巧。

一段使用宏定义日志接口的代码:

#include <stdarg.h>
#include <string.h>
#ifdef NMEDIA_SUPPORT_MINILOG
#include "minilogger/log.h"
#endif
#include "rkmedia_common.h"

#define LOG_LEVEL_ERROR 0
#define LOG_LEVEL_WARN 1
#define LOG_LEVEL_INFO 2
#define LOG_LEVEL_DBG 3

#ifndef MOD_TAG
#define MOD_TAG RK_ID_SYS
#endif

extern short g_level_list[RK_ID_BUTT];
extern int nmedia_log_method;
extern const char *mod_tag_list[RK_ID_BUTT];

#define LOG_LEVEL_JUDGE(FILTER_LEVEL)                                          \
  {                                                                            \
    if (g_level_list[MOD_TAG] < FILTER_LEVEL)                                  \
      break;                                                                   \
  }

#ifdef NMEDIA_SUPPORT_MINILOG
#define NMEDIA_LOGE(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_ERROR);                                          \
    minilog_error("[NMEDIA][%s][Error]:" format, mod_tag_list[MOD_TAG],       \
                  ##__VA_ARGS__);                                              \
  } while (0)

#define NMEDIA_LOGW(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_WARN);                                           \
    minilog_warn("[NMEDIA][%s][Warn]:" format, mod_tag_list[MOD_TAG],         \
                 ##__VA_ARGS__);                                               \
  } while (0)

#define NMEDIA_LOGI(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_INFO);                                           \
    minilog_info("[NMEDIA][%s][Info]:" format, mod_tag_list[MOD_TAG],         \
                 ##__VA_ARGS__);                                               \
  } while (0)

#define NMEDIA_LOGD(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_DBG);                                            \
    minilog_debug("[NMEDIA][%s][Debug]:" format, mod_tag_list[MOD_TAG],       \
                  ##__VA_ARGS__);                                              \
  } while (0)

#else // NMEDIA_SUPPORT_MINILOG

#define NMEDIA_LOGE(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_ERROR);                                          \
    fprintf(stderr, "[NMEDIA][%s][Error]:" format, mod_tag_list[MOD_TAG],     \
            ##__VA_ARGS__);                                                    \
  } while (0)

#define NMEDIA_LOGW(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_WARN);                                           \
    fprintf(stderr, "[NMEDIA][%s][Warn]:" format, mod_tag_list[MOD_TAG],      \
            ##__VA_ARGS__);                                                    \
  } while (0)

#define NMEDIA_LOGI(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_INFO);                                           \
    fprintf(stderr, "[NMEDIA][%s][Info]:" format, mod_tag_list[MOD_TAG],      \
            ##__VA_ARGS__);                                                    \
  } while (0)

#define NMEDIA_LOGD(format, ...)                                              \
  do {                                                                         \
    LOG_LEVEL_JUDGE(LOG_LEVEL_DBG);                                            \
    fprintf(stderr, "[NMEDIA][%s][Debug]:" format, mod_tag_list[MOD_TAG],     \
            ##__VA_ARGS__);                                                    \
  } while (0)
#endif // NMEDIA_SUPPORT_MINILOG

宏日志的好处:

  1. 性能优化:宏定义在预处理阶段进行替换,因此编译器将宏定义的日志函数直接替换为实际的日志函数调用,从而避免了函数调用的开销。对于频繁调用情况会显著提高程序的性能。

  2. 条件编译:使用宏定义,可以在不同的编译条件下选择不同的日志函数实现。例如,可以根据系统环境或者编译器环境的不同选择不同的底层日志实现。也能够做到可以在调试版本中使用更详细的日志输出,而在发布版本中只输出错误日志。

    • 这段代码中就所有体现NMEDIA_SUPPORT_MINILOG这个宏可以在cmake中事先定义或者不定义,通过它可以决定日志底层接口使用哪个。
  3. 灵活性:宏定义可以接受可变参数,这使得日志函数可以接受不同数量的参数,从而提供了更大的灵活性。例如,可以使用printf风格的格式字符串来格式化日志消息。

  4. 易于修改:由于宏定义是预处理器指令,因此可以在不修改源代码的情况下修改日志函数的行为。例如,可以通过修改宏定义中的日志级别判断条件来控制日志的输出级别。

    • g_level_list[MOD_TAG]代表某一个模块等级
  5. 代码复用:宏定义定义在头文件中,在不同的源文件中复用。日志宏的实现可以在多个模块中共享,从而提高了代码的复用性。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值