如何用printf写一个自己的日志打印系统?("手把手教你用printf打造专属日志打印系统")

原创
ithorizon 1个月前 (10-20) 阅读数 14 #后端开发

手把手教你用printf打造专属日志打印系统

一、引言

在软件开发过程中,日志系统是不可或缺的一部分。它帮助我们跟踪程序的运行状态,调试程序中的谬误,以及记录关键信息。今天,我们将使用C语言中的printf函数,来构建一个简洁的日志打印系统。

二、日志打印系统的基本需求

一个基本的日志系统应该具备以下功能:

  • 拥护不同级别的日志输出,如INFO、WARN、ERROR等。
  • 能够输出日志的时间戳。
  • 拥护日志输出到不同的目标,如控制台、文件等。

三、日志级别的定义

首先,我们需要定义日志级别。通常,日志级别包括DEBUG、INFO、WARN、ERROR等。我们可以使用枚举类型来定义这些级别:

typedef enum {

LOG_LEVEL_DEBUG,

LOG_LEVEL_INFO,

LOG_LEVEL_WARN,

LOG_LEVEL_ERROR

} LogLevel;

四、日志打印函数的设计

接下来,我们设计日志打印函数。这个函数需要接收日志级别、格式化字符串和可变参数。我们使用vfprintf函数来输出到不同的目标,使用vasprintf来格式化字符串。

#include

#include

#include

void log_print(const char *file, int line, LogLevel level, const char *fmt, ...) {

va_list args;

va_start(args, fmt);

// 获取当前时间

time_t now = time(NULL);

struct tm *tm_info = localtime(&now);

char time_str[20];

strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info);

// 打印日志级别和时间

printf("[%s] [%s:%d] ", time_str, file, line);

// 打印日志内容

vprintf(fmt, args);

// 终结可变参数的获取

va_end(args);

// 打印换行符

printf(" ");

}

五、日志宏的定义

为了方便使用,我们可以定义一些宏来简化日志打印的操作。这些宏会利用日志级别自动填充文件名和行号信息。

#define LOG_DEBUG(fmt, ...) log_print(__FILE__, __LINE__, LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)

#define LOG_INFO(fmt, ...) log_print(__FILE__, __LINE__, LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)

#define LOG_WARN(fmt, ...) log_print(__FILE__, __LINE__, LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)

#define LOG_ERROR(fmt, ...) log_print(__FILE__, __LINE__, LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)

六、使用日志系统

现在,我们可以使用我们自定义的日志系统来打印日志了。以下是一个示例代码:

#include "log.h" // 假设我们将上面的代码保存在log.h中

int main() {

LOG_DEBUG("This is a debug message.");

LOG_INFO("This is an info message.");

LOG_WARN("This is a warning message.");

LOG_ERROR("This is an error message.");

return 0;

}

七、日志输出到文件

如果需要将日志输出到文件,我们可以稍微修改日志打印函数,使其能够打开文件并写入。这里我们假设日志文件名是固定的,比如"log.txt"。

void log_print_to_file(const char *file, int line, LogLevel level, const char *fmt, ...) {

FILE *fp = fopen("log.txt", "a");

if (fp == NULL) {

printf("Failed to open log file. ");

return;

}

va_list args;

va_start(args, fmt);

// 获取当前时间

time_t now = time(NULL);

struct tm *tm_info = localtime(&now);

char time_str[20];

strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", tm_info);

// 写入日志级别和时间

fprintf(fp, "[%s] [%s:%d] ", time_str, file, line);

// 写入日志内容

vfprintf(fp, fmt, args);

// 终结可变参数的获取

va_end(args);

// 写入换行符并关闭文件

fprintf(fp, " ");

fclose(fp);

}

同样地,我们可以定义相应的宏来简化文件日志的打印:

#define LOG_DEBUG_TO_FILE(fmt, ...) log_print_to_file(__FILE__, __LINE__, LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__)

#define LOG_INFO_TO_FILE(fmt, ...) log_print_to_file(__FILE__, __LINE__, LOG_LEVEL_INFO, fmt, ##__VA_ARGS__)

#define LOG_WARN_TO_FILE(fmt, ...) log_print_to_file(__FILE__, __LINE__, LOG_LEVEL_WARN, fmt, ##__VA_ARGS__)

#define LOG_ERROR_TO_FILE(fmt, ...) log_print_to_file(__FILE__, __LINE__, LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)

八、总结

通过本文,我们使用C语言的printf函数构建了一个简洁的日志打印系统。这个系统拥护不同级别的日志输出,并且可以输出到控制台或者文件。在实际项目中,可以利用需要进一步扩展和优化这个系统,比如提高日志过滤、日志轮转等功能。

以上是一个使用HTML标签编写的文章,其中包含了怎样使用printf函数构建一个简洁的日志打印系统的详细步骤和代码示例。

本文由IT视界版权所有,禁止未经同意的情况下转发

文章标签: 后端开发


热门