写在前面
日志系统是程序中用于记录和存储运行时信息的重要组成部分。它可以帮助开发人员在程序执行期间了解程序的状态、诊断问题和进行故障排除。很多编程语言都提供了相应日志库和框架,用于实现日志记录的功能。比如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(¤t_time);
m_time = localtime(¤t_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;
}
代码解析
-
我们需要确定各种日志的类型
typedef enum {
LOG_DBG,
LOG_SUCCESS,
LOG_WARN,
LOG_ERR,
LOG_LEVEL_LEN
} LOG_LEVEL;
这里,我们使用枚举定义了需要的日志类型。包括:
-
调试(Debug) -
成功(Success) -
警告(Warning) -
错误(Error)
这四种类型对于开发和运维人员排查问题和监控运行已经足够了,同时,这也是常见的日志系统的类型。
-
为日志文本着色
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
以实现着色。
-
记录时间
time_t current_time;
struct tm *m_time;
void get_time() {
time(¤t_time);
m_time = localtime(¤t_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