在软件开发中,日志记录是一项非常重要的功能,它有助于追踪程序的运行状态、调试问题以及监控性能。在 C 语言中,可以通过封装日志记录功能来创建一个可重复使用的日志模块。下面是一个简单的日志记录模块的示例,该模块支持不同的日志级别,并可以输出到标准输出或文件。
日志级别定义定义几个宏来表示不同的日志级别。
1#define LOG_DEBUG 02#define LOG_INFO 13#define LOG_WARN 24#define LOG_ERROR 35#define LOG_FATAL 4日志配置定义日志配置宏,包括日志级别和日志输出的位置。
1#define LOG_LEVEL LOG_INFO // 设置默认的日志级别2#define LOG_FILE "log.txt" // 日志文件名日志记录宏定义一系列宏来记录不同级别的日志信息。
1#include <stdio.h>2#include <stdarg.h>3#include <string.h>4#include <time.h>56// 日志记录宏7#define LOG(level, fmt, ...) do { \8 if (level <= LOG_LEVEL) { \9 fprintf(stderr, "[%s] ", logLevelToString(level)); \10 vfprintf(stderr, fmt, __VA_ARGS__); \11 fputc('\n', stderr); \12 if (strcmp(__FILE__, "<stdin>") != 0) { \13 FILE *logfile = fopen(LOG_FILE, "a"); \14 if (logfile) { \15 fprintf(logfile, "[%s] ", logLevelToString(level)); \16 vfprintf(logfile, fmt, __VA_ARGS__); \17 fputc('\n', logfile); \18 fclose(logfile); \19 } \20 } \21 } \22} while(0)2324// 将日志级别转换为字符串25static const char *logLevelToString(int level) {26 switch (level) {27 case LOG_DEBUG: return "DEBUG";28 case LOG_INFO: return "INFO";29 case LOG_WARN: return "WARN";30 case LOG_ERROR: return "ERROR";31 case LOG_FATAL: return "FATAL";32 default: return "UNKNOWN";33 }34}示例代码下面是一个使用上述日志模块的示例。
1#include <stdio.h>2#include <string.h>34// 包含日志宏定义5#include "log.h" // 假设 log.h 包含上面定义的日志宏67int main() {8 LOG_DEBUG("Debug message.");9 LOG_INFO("Informational message.");10 LOG_WARN("Warning message.");11 LOG_ERROR("Error message.");12 LOG_FATAL("Fatal error.");1314 return 0;15}解释日志级别定义:定义了五个日志级别:LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL。日志配置:定义了 LOG_LEVEL 宏来设置最低的日志级别。定义了 LOG_FILE 宏来指定日志文件的名称。日志记录宏:LOG 宏用于记录日志,它接受日志级别、格式字符串和可变参数列表。使用 vfprintf 函数来处理可变参数列表。如果日志级别低于设定的最低级别,则不会记录这条日志。日志会被输出到标准输出(stderr)和指定的日志文件中。日志级别字符串转换函数:logLevelToString 函数将日志级别转换为对应的字符串表示。使用注意事项确保在实际项目中包含日志模块的头文件。调整 LOG_LEVEL 和 LOG_FILE 以适应您的需求。日志文件可能会随着时间积累大量数据,因此需要定期清理或轮换。如果您的程序需要更高级的日志功能,例如日志过滤、多线程支持等,可以考虑使用成熟的日志库,如 Log4C 或 JULIA。通过这种方式封装日志记录功能,您可以轻松地在不同的项目中重复使用这些代码,并且可以根据需要调整日志级别和输出位置。