我们在开发时,日志的输出是直接将标准输入和标准错误重定向到一个指定的文件中,这种方式不太适合产品化,需要新增一种日志输出方式,满足企业级服务的日常运维所需。
如果要是自研日志组件的话,定制化能力虽然强,但是工作量较大,后续维护复杂度较高 所以考虑相关依赖工具成熟度,工作量大小,后期维护方便等等因素,推荐你试一下linux自带的syslog服务。
接下来以开发SPDK的日志模块为例来讲解syslog。
syslog组件使用
syslog() 函数解析
syslog() 是 Unix/Linux 系统用于发送日志到系统日志服务的函数:
头文件与原型:
#include <syslog.h>
void syslog(int priority, const char *format, ...);
关键参数:
- priority:日志优先级,由 设施码 和 级别 组合而成(如 LOG_DAEMON | LOG_ERR)
- format:格式化字符串,类似 printf()
- ...:可变参数列表
syslog 协议的优先级级别,定义在 POSIX 标准库中:
- 头文件:
<syslog.h>(Unix/Linux 系统) - 标准归属:POSIX 标准,非 C 语言核心标准(但几乎所有 Unix 系统都支持)
- 常见定义:
#define LOG_EMERG 0 /* 系统不可用 */
#define LOG_ALERT 1 /* 必须立即处理 */
#define LOG_CRIT 2 /* 严重错误 */
#define LOG_ERR 3 /* 一般错误 */
#define LOG_WARNING 4 /* 警告 */
#define LOG_NOTICE 5 /* 正常但重要的事件 */
#define LOG_INFO 6 /* 信息性消息 */
#define LOG_DEBUG 7 /* 调试信息 */
初始化连接(可选):
openlog("myapp", LOG_PID | LOG_CONS, LOG_DAEMON);
// 参数:标识字符串、选项标志、默认设施
发送日志:
syslog(LOG_ERR, "Failed to open file: %s", strerror(errno));
syslog(LOG_INFO, "Process started with PID %d", getpid());
关闭连接(可选):
closelog();
SPDK 中 syslog() 的应用
在 spdk_vlog() 函数中:
优先级映射:
switch (level) {
case SPDK_LOG_ERROR: severity = LOG_ERR; break;
case SPDK_LOG_WARN: severity = LOG_WARNING; break;
// ...
}
日志发送:
syslog(severity, "%s:%4d:%s: %s: %s", file, line, func, level_name, msg);
输出示例:
Jul 11 15:09:52 oe-rd-3 spdk[513824]: bdev_sheepdog.c:1612:bdev_sheepdog_create_cb: *NOTICE*: create callback, tid: 140302486038912, ch: 0x26e7390, disk: chenditest1 0x26e5180
syslog日志配置
在 Linux 系统中,syslog 的日志文件路径由 系统日志服务配置 决定,而非直接在代码中设置。以下是详细说明:
syslog主配置文件
日志存储位置由系统配置文件(如 /etc/rsyslog.conf)决定
可通过设施码和级别进行精细过滤
示例配置片段:
将所有日志发送到 /var/log/syslog
*.info;mail.none;authpriv.none;cron.none /var/log/syslog
将 authpriv 设施的所有级别发送到 /var/log/auth.log
authpriv.* /var/log/auth.log
将 cron 设施的所有级别发送到 /var/log/cron.log
cron.* /var/log/cron.log
自定义规则:将所有 LOG_ERR 级别的日志发送到 /var/log/errors
*.err /var/log/errors
关键配置语法说明
rsyslog 选择器语法
facility.priority action
# 示例
authpriv.* /var/log/auth.log # 所有 authpriv 设施的日志
*.err /var/log/errors # 所有设施的错误级别日志
常用设施 (facility)
|
设施名 |
说明 |
|
kern |
内核消息 |
|
user |
用户级消息 |
|
|
邮件系统 |
|
daemon |
系统守护进程 |
|
auth |
认证系统 |
|
local0-7 |
本地自定义设施(常用) |
常用优先级 (priority)
从高到低:emerg > alert > crit > err > warning > notice > info > debug
配置 SPDK 日志写入特定文件
修改系统配置:
在 /etc/rsyslog.d/ 中创建新配置文件(如 spdk.conf):
:programname, isequal, "spdk" /vm_data/spdk/spdk.log
:programname, isequal, "spdk" ~
~:是 rsyslog 的特殊符号,表示 “丢弃”(discard)。即匹配的日志不再继续向下传递给其他规则,也不会写入默认的系统日志文件(如/var/log/messages等)。这条规则的作用是:避免spdk_ebs的日志被重复处理或写入其他默认日志文件,确保其日志只出现在第一条规则指定的spdk.log中。
重启 rsyslog 服务:
sudo systemctl restart rsyslog
logrotate 工具实现日志切分
logrotate 是 Linux 系统中用于管理日志文件轮转的工具,可以设置按天、按周等方式对日志进行切分、压缩等操作。
- 编辑 logrotate 配置文件:打开
/etc/logrotate.d/rsyslog文件,如果文件不存在可自行创建。 - 添加轮转规则:在文件中添加以下内容:
/var/log/syslog {
daily
create 640 root adm
rotate 7
compress
missingok
notifempty
}
上述配置中,daily表示每天轮转一次日志文件;create 640 root adm用于设置轮转后创建新日志文件的权限、属主和属组;rotate 7表示保留 7 个轮转后的日志文件;compress表示压缩轮转后的日志文件;missingok表示如果日志文件丢失,不报错;notifempty表示如果日志文件为空,则不进行轮转。
3. 重启 rsyslog 服务:执行sudo systemctl restart rsyslog命令,使配置生效。



1万+

被折叠的 条评论
为什么被折叠?



