目录
一、什么是syslog协议
syslog
协议是一种标准化的方法,用于在网络设备间传输日志信息,允许各种设备如服务器、路由器、防火墙等,将日志消息发送至中央日志服务器,便于集中管理与分析。以下是syslog
协议的关键概念和组成部分:
1. 协议版本
- RFC 3164: 早期的
syslog
协议规范,定义了基本的消息格式和传输机制。 - RFC 5424: 更新的规范,提供了更严格的消息格式和增强的安全特性,如使用TLS进行加密传输。
2. 消息结构
一个syslog
消息通常包含:
- 头部: 包含优先级字段(
<pri>
),由设施和严重性组成。 - 时间戳: 记录消息产生的时间。
- 主机名: 发送消息的设备名称。
- 应用程序名: 产生日志的应用程序或进程名称。
- 进程ID: 可选,标识产生日志的进程。
- 消息ID: 可选,用于标识特定类型的消息。
- 结构化数据: 可选,包含键值对形式的额外信息。
- 消息体: 实际的日志文本。
3. 设施与严重性
- 设施: 定义日志消息的来源,如用户级进程、系统级进程等。
- 严重性: 定义消息的紧急程度,从紧急(0)到调试(7)。
4. 传输协议
syslog
消息可通过不同协议发送:
- UDP: 默认的无连接协议,提供低延迟但不可靠的传输。
- TCP: 提供可靠的消息传输,可能有更高延迟。
- TLS/SSL: 提供安全的传输,防止消息被截获或篡改。
5. 服务器与客户端
- syslog服务器: 接收并处理来自多源的
syslog
消息,可存储、过滤和转发。 - syslog客户端: 产生日志消息并发送给
syslog
服务器。
6. 实现工具
- rsyslog: 流行的
syslog
守护进程,用于Linux和Unix系统,提供高级功能如过滤、重定向。 - syslog-ng: 强大的
syslog
守护进程,提供高可用性和性能。
syslog
协议在网络安全、故障排除及合规性方面至关重要,因为它允许组织集中监控和分析来自网络基础设施的日志数据。
二、Linux 系统日志服务程序
systemd-journald
, syslogd
, 和 rsyslog
都是常见的系统日志服务,各自有不同的特点和功能:
1. systemd-journald
- 功能:systemd-journald 是 systemd 提供的日志管理服务,用于收集、存储和检索日志数据。
- 特点:它采用二进制格式存储日志,支持结构化数据和元数据,并能够根据需求动态调整日志存储大小。它与 systemd 协作紧密,可以使用
journalctl
命令来查询和管理日志。
2. syslogd
- 功能:syslogd 是传统的 Unix/Linux 系统上的基本日志守护进程,负责接收、处理和存储系统和应用程序生成的日志消息。
- 特点:它通常将日志消息以文本格式写入指定的日志文件,如
/var/log/messages
、/var/log/syslog
等。syslogd 的功能相对简单,适合基本的日志记录需求。
3. rsyslog
- 功能:rsyslog 是 syslogd 的增强版,提供了更多的功能和灵活性,支持复杂的日志消息过滤、转发、格式化等操作。
- 特点:与传统的 syslogd 不同,rsyslog 支持 TCP 和 TLS 连接,能够进行远程日志记录和集中式日志管理,适用于复杂的日志收集和分发场景。
4. 使用场景和选择
-
systemd-journald 适合于使用 systemd 的系统,它提供了现代化的日志管理功能,支持结构化数据和强大的查询能力,特别适合于系统级日志分析和诊断。
-
syslogd 适合于传统的 Unix/Linux 系统,它轻量级且稳定,对于简单的日志记录和本地存储需求足够。
-
rsyslog 则适合于需要更高级日志管理功能的环境,如复杂的网络环境或需要远程日志记录的场景,它的灵活性和扩展性比较高。
在实际使用中,选择日志服务应根据具体需求和系统环境来决定。例如,对于现代化的 systemd 系统,推荐使用 systemd-journald 来利用其先进的功能和集成优势;而对于传统 Unix/Linux 系统,可以选择使用 syslogd 或 rsyslog,根据具体的日志管理需求来进行配置和部署。
三、Linux syslog协议相关的API
openlog
, closelog
, 和 syslog
是用于在 C 语言中进行系统日志记录的标准函数,通常与 syslogd
或 rsyslog
等日志守护进程配合使用。它们的功能和使用方法如下:
1. openlog
void openlog(char *ident, int option, int facility);
-
功能:
openlog
函数用于初始化系统日志记录。它告诉系统如何处理后续的日志消息。 -
参数解释:
ident
:一个字符串,通常是程序的名字或标识符,用于标记日志消息的来源。可以为 NULL,表示使用默认标识符。option
:用于指定日志记录的选项,可以使用LOG_CONS
、LOG_NDELAY
、LOG_NOWAIT
等常量,控制日志写入的行为。facility
:指定日志消息的设施(facility),如LOG_USER
、LOG_LOCAL0
到LOG_LOCAL7
等,用于标识日志消息的类别。
2. closelog
void closelog();
- 功能:
closelog
函数关闭之前使用openlog
打开的日志系统。在程序结束时调用,确保清理和关闭日志记录。
3. syslog
void syslog(int priority, char *format, ...);
-
功能:
syslog
函数用于向系统日志写入一条消息。 -
参数解释:
priority
:日志消息的优先级,可以使用LOG_EMERG
、LOG_ALERT
、LOG_ERR
、LOG_WARNING
、LOG_INFO
等常量来表示不同的日志级别。format
:格式化字符串,类似于printf
的格式,用于指定日志消息的内容。...
:格式化字符串后面的参数,用于填充格式化字符串中的占位符。
4. 使用详解
(1)初始化日志系统:在程序开始时通常会调用 openlog
来初始化日志系统,指定程序标识符和日志设施。
openlog("myprogram", LOG_PID, LOG_USER);
这里指定了程序标识符为 “myprogram”,使用 LOG_PID
选项告诉系统记录每条日志消息的进程 ID,使用 LOG_USER
设施表示这些日志消息属于用户级别。
(2) 记录日志消息:在程序中需要记录日志时,使用 syslog
函数来写入日志消息。
syslog(LOG_INFO, "This is an informational message");
这条语句将一条信息级别的日志消息写入系统日志,内容为 “This is an informational message”。
(3) 关闭日志系统:在程序结束时,调用 closelog
来关闭日志系统,释放相关资源。
closelog();
通过这些函数,程序可以方便地与系统日志守护进程进行交互,记录各种级别和类型的日志消息,帮助管理员监视和诊断应用程序的运行状态和问题。
5. 示例代码
#include <syslog.h>
int main()
{
// 打开日志,设置日志标识符为 "example"
openlog("example", LOG_PID|LOG_CONS, LOG_USER);
// 写入日志消息
syslog(LOG_INFO, "This is an informational message.");
syslog(LOG_WARNING, "This is a warning message.");
syslog(LOG_ERR, "This is an error message.");
// 关闭日志
closelog();
return 0;
}
这段代码展示了如何使用 syslog
函数库来写入不同优先级的日志消息。具体说明如下:
-
openlog("example", LOG_PID|LOG_CONS, LOG_USER);
:打开日志,设置日志标识符为 “example”,并指定选项LOG_PID
(在每条日志消息中包含进程ID)和LOG_CONS
(如果无法写入日志,则将消息输出到控制台)。LOG_USER
表示使用USER
设施来存储日志。 -
syslog(LOG_INFO, "This is an informational message.");
:写入一条信息级别的日志消息。 -
syslog(LOG_WARNING, "This is a warning message.");
:写入一条警告级别的日志消息。 -
syslog(LOG_ERR, "This is an error message.");
:写入一条错误级别的日志消息。 -
closelog();
:关闭日志。
在实际使用中,日志消息会被发送到配置好的日志存储位置,比如对于syslogd
日志服务程序来说,默认存储在 /var/log/messages
文件。有的系统经过配置后也可能存储在/var/log/syslog
。
四、嵌入式Linux主控使用日志服务
在嵌入式 Linux 主控上,一般使用busybox构建根文件系统,busybox的成果物中包含了syslogd程序,其可提供日志服务。比如记录内核日志。
syslogd
通常通过 Syslog 协议(即 UDP 端口 514)接收来自系统和服务器的日志信息。它们并不直接从内核中获取日志信息,而是系统服务或应用程序通过调用标准库函数 syslog()
将日志消息发送到对应端口。具体过程如下:
-
内核事件产生:在内核中,当发生某些事件时,系统函数会根据配置写日志到
/proc/kmsg
或/dev/kmsg
。 -
klogd 读取内核日志:守护进程
klogd
(也是busybox成果物)会定期读取/proc/kmsg
或者/dev/kmsg
来捕获内核日志。klogd
收到内核日志后,会根据自己的配置进行必要的处理,然后通过 Syslog 协议(UDP 或 Syslog 传输控制协议 TCP 端口 514)将这些消息发送到syslogd
。 -
syslogd 或 rsyslogd 接收:
syslogd
守护进程运行在用户空间,它们会监听 UDP 端口 514 来接收来自klogd
或者其他系统服务或应用程序的日志消息。例如《三、Linux syslog协议相关的API》中提供的示例代码,编译执行后也会有相关日志信息存储在/var/log/messages
文件。 -
存储和处理:接收到日志消息后,
syslogd
根据配置将日志消息存储到指定的日志文件中,并进行相应的处理,如格式化、过滤、转发等。
再比如我们的用户控制台登陆,其会用到busybox成果物中的login程序,这个程序中也会调用syslog接口发送日志,将登陆相关信息记录在/var/log/messages
文件。SSH登陆信息的记录也类似,Dropbear这个轻量级的ssh程序内部也会调用syslog接口。
五、扩展阅读(优质好文)
Linux系统中的日志管理
Linux 日志管理journald和rsyslog
syslog详解及配置远程发送日志和远程日志分类
syslog 详解
欢迎大家指导和交流!如果我有任何错误或遗漏,请立即指正,我愿意学习改进。期待与大家一起进步!