写点什么

日志 | AI 工程化部署

作者:AIWeker
  • 2023-12-15
    福建
  • 本文字数:1841 字

    阅读完需:约 6 分钟

日志

日志在任何一种语言编程中都会涉及到,python 中有 logging 库,java 中有 log4j。当然 C 也有日志功能,一般可以用宏和函数来实现。


需要明确下日志的功能,一般会设置一个日志等级,比如 trace < debug < info < warn < error < fatal 等,根据设置的等级高低来判断是否显示日志。

宏实现

可以使用宏定义和条件编译来实现一个简单的日志函数,如下所示:


#include <stdio.h>
// 定义日志等级#define LOG_LEVEL_DEBUG 0#define LOG_LEVEL_INFO 1#define LOG_LEVEL_WARN 2#define LOG_LEVEL_ERROR 3
// 定义日志级别#ifndef LOG_LEVEL#define LOG_LEVEL LOG_LEVEL_INFO#endif
// 定义日志函数#define LOG(level, format, ...) \ do { \ if (level >= LOG_LEVEL) { \ printf("[%s] " format "\n", #level, ##__VA_ARGS__); \ } \ } while(0)
int main() { int value = 42; LOG(LOG_LEVEL_DEBUG, "Debug message, value = %d", value); LOG(LOG_LEVEL_INFO, "Info message, value = %d", value); LOG(LOG_LEVEL_WARN, "Warning message, value = %d", value); LOG(LOG_LEVEL_ERROR, "Error message, value = %d", value); return 0;}
复制代码


在这个例子中,我们定义了四个日志级别,并使用宏定义和条件编译来控制日志输出的级别。在main函数中,我们使用LOG宏输出不同级别的日志信息。


您可以根据您的需要修改LOG_LEVEL的值来控制输出的日志级别。


这里##__VA_ARGS__是一个预处理器的特殊标记,用于处理可变参数列表。这个标记的作用是将可变参数列表展开并与它前面的文本连接起来。通常,##__VA_ARGS__用于定义带有可变参数的宏。当宏被调用时,##__VA_ARGS__会将可变参数列表展开,并将展开后的参数直接与宏定义中的文本相连接。

函数实现

我们创建一个名为log的函数,函数接受日志级别和消息作为参数,并在函数内部根据日志级别输出相应的日志信息。以下是一个使用函数来实现日志功能的示例代码:


#include <stdio.h>
// 定义日志等级typedef enum { LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARN, LOG_LEVEL_ERROR} LogLevel;
// 定义日志函数void log(LogLevel level, const char *format, ...) { va_list args; va_start(args, format); if (level == LOG_LEVEL_DEBUG) { printf("[DEBUG] "); } else if (level == LOG_LEVEL_INFO) { printf("[INFO] "); } else if (level == LOG_LEVEL_WARN) { printf("[WARN] "); } else if (level == LOG_LEVEL_ERROR) { printf("[ERROR] "); } vprintf(format, args); printf("\n"); va_end(args);}
int main() { int value = 42; log(LOG_LEVEL_DEBUG, "Debug message, value = %d", value); log(LOG_LEVEL_INFO, "Info message, value = %d", value); log(LOG_LEVEL_WARN, "Warning message, value = %d", value); log(LOG_LEVEL_ERROR, "Error message, value = %d", value); return 0;}
复制代码


在这个例子中,我们定义了一个枚举类型LogLevel来表示不同的日志级别,然后创建了一个log函数来处理日志输出。在main函数中,我们使用log函数输出不同级别的日志信息。


这种方法不使用宏,而是使用了函数来实现日志功能,使得日志功能更加灵活和易于维护。


值得注意的是:在这个函数声明中,"..."表示可变参数列表。这意味着函数可以接受任意数量的参数。在 C 语言中,可变参数列表通常使用 stdarg.h 中的宏来处理。在函数内部,可以使用这些宏来访问传递的可变参数。


另外,在 C 语言中,va_list、va_start 和 va_end 是用于处理可变参数列表的宏和函数。


  1. va_list: va_list 是一个类型,用于声明一个指向参数列表的指针。它是一个指向参数列表的指针,可以用于遍历参数列表中的每个参数。

  2. va_start: va_start 宏用于初始化可变参数列表的遍历。它接受两个参数,第一个是一个 va_list 类型的变量,第二个是可变参数列表中的最后一个固定参数。va_start 会将指向参数列表的指针指向第一个可变参数。

  3. va_end: va_end 宏用于结束可变参数列表的遍历。它接受一个参数,即 va_list 类型的变量。va_end 会清理可变参数列表的状态,确保不会出现内存泄露。


使用这些宏和函数,可以在函数内部遍历可变参数列表,获取每个参数的值,并进行相应的处理。这在需要处理不定数量参数的函数中非常有用,比如 printf 函数就是一个典型的例子。

发布于: 刚刚阅读数: 4
用户头像

AIWeker

关注

InfoQ签约作者 / 公众号:人工智能微客 2019-11-21 加入

人工智能微客(aiweker)长期跟踪和分享人工智能前沿技术、应用、领域知识,不定期的发布相关产品和应用,欢迎关注和转发

评论

发布
暂无评论
日志 | AI工程化部署_c_AIWeker_InfoQ写作社区