写一个C语言日志系统竟然这么简单

写在前面

日志系统是程序中用于记录和存储运行时信息的重要组成部分。它可以帮助开发人员在程序执行期间了解程序的状态、诊断问题和进行故障排除。很多编程语言都提供了相应日志库和框架,用于实现日志记录的功能。比如Python 的标准库 logging,Java 的log4j等。本文我们将手动构建一个 C 语言的日志系统。

实现

Talk is cheap. Show me the code.

— Linus Torvalds

我们直接贴代码

#include <stdio.h>
#include <stdarg.h>
#include <time.h>

typedef enum {
    LOG_DBG,
    LOG_SUCCESS,
    LOG_WARN,
    LOG_ERR,
    LOG_LEVEL_LEN
} LOG_LEVEL;

#ifdef __EMSCRIPTEN
    #define NO_ANSI
#endif

char * type[LOG_LEVEL_LEN] = {
    "DEBUG",
    "SUCCESS",
    "WARN",
    "ERR"
}; 

char * colors[LOG_LEVEL_LEN] = {
    "x1b[0m",
    "x1b[32m",
    "x1b[1;33m",
    "x1b[31m"
};

time_t current_time;
struct tm * m_time; 

void get_time() {
    time(&current_time);
    m_time = localtime(&current_time);
}

void ulogger_log(LOG_LEVEL level, const char * fmt, ...) {
    va_list args;
    va_start(args, fmt);
        get_time();
        #ifndef NO_ANSI 
            printf("%s", colors[level]);
        #endif
        
        printf("[%d/%d/%d -> %d:%d:%d][%s] ", m_time -> tm_mday,
                                        m_time -> tm_mon,
                                        m_time -> tm_year + 1900,
                                        m_time -> tm_hour, 
                                        m_time -> tm_min, 
                                        m_time -> tm_sec,
                                        type[level]); 
        vfprintf(stdout, fmt, args);
        printf("n%s", colors[LOG_DBG]);
    va_end(args);
}

int main() {
    LOG_LEVEL level = LOG_DBG;
    ulogger_log(level, "This is a log message: %s""Hello, World!");

    return 0;
}

代码解析

  1. 我们需要确定各种日志的类型
typedef enum {
    LOG_DBG,
    LOG_SUCCESS,
    LOG_WARN,
    LOG_ERR,
    LOG_LEVEL_LEN
} LOG_LEVEL;

这里,我们使用枚举定义了需要的日志类型。包括:

  • 调试(Debug)
  • 成功(Success)
  • 警告(Warning)
  • 错误(Error)

这四种类型对于开发和运维人员排查问题和监控运行已经足够了,同时,这也是常见的日志系统的类型。

  1. 为日志文本着色
char *type[LOG_LEVEL_LEN] = {
    "DEBUG",
    "SUCCESS",
    "WARN",
    "ERR"
}; 

char *colors[LOG_LEVEL_LEN] = {
    "x1b[0m",      // 白色
    "x1b[32m",     // 绿色
    "x1b[1;33m",   // 黄色
    "x1b[31m"      // 红色
};

这里,我们将存储了 LOG_LEVEL_LEN,因为我们将在代码中使用它来为日志和文本设置ANSI-codes以实现着色。

  1. 记录时间
time_t current_time;
struct tm *m_time; 

void get_time() {
    time(&current_time);
    m_time = localtime(&current_time);
}

我们将存储时间,以便使用 time.h 中的时间结构来显示日志的时间,并定义了 get_time 函数用于获取当前时间。

定义日志函数

我们已经定义了一个基础的 C 语言日志系统,那么如何使用日志呢?下面,我们将编写一个函数,该函数可以接收以下参数:日志类型、格式、任意额外的参数。在编写函数之前,我们还需要包含 stdarg.h,以便在 C 语言中使用 va_list 进行可变参数解析。现在我们的函数如下所示:

void ulogger_log(LOG_LEVEL level, const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);
        get_time();
        #ifndef NO_ANSI 
            printf("%s", colors[level]);
        #endif
        
        printf("[%d/%d/%d -> %d:%d:%d][%s] ", m_time->tm_mday,
                                        m_time->tm_mon,
                                        m_time->tm_year + 1900,
                                        m_time->tm_hour, 
                                        m_time->tm_min, 
                                        m_time->tm_sec,
                                        type[level]); 
        vfprintf(stdout, fmt, args);
        printf("n%s", colors[LOG_DBG]);
    va_end(args);
}

这个函数做了一下事情。

  • 声明了 va_list 并使用 va_start 函数解析参数。
  • 获取时间并简单地输出颜色代码。

最后,我们输出第一个颜色,即白色,因为颜色保持不变,除非更改它,所以我们只需更改颜色并停止解析参数。该系统非常简单。

使用日志系统

我们已经完成了 C 语言日志系统的编写,那么如何使用日志呢?

int main() {
    LOG_LEVEL level = LOG_DBG;
    ulogger_log(level, "This is a log message: %s""Hello, World!");

    return 0;
}

这里我们看到只需要调用ulogger_log()函数并传入对应参数即可。输出结果

[12/3/2024 -> 18:30:15][DEBUG] This is a log message: Hello, World!

写在最后

到这里我们就完成了C语言日志系统编写的学习,但是,这只实现了基本的记录并显示日志信息。你也可以根据需要进行扩展和定制,以满足不同的日志记录需求。


原文始发于微信公众号(harvey的网络日志):写一个C语言日志系统竟然这么简单

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/239381.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!