第2章 Syslog协议基础
说到日志收集,Syslog 是绕不开的老大哥。它从 80 年代诞生到现在,几乎成了日志领域的通用语言。你想想看,无论是路由器、交换机,还是 Linux 服务器、各类中间件,提到日志输出,第一反应就是 Syslog。这一章我们就把它彻底讲透。
2.1 从 RFC 3164 到 RFC 5424
Syslog 最早是 BSD 系统里的一个打印服务,那时候没什么标准可言。2001 年有了 RFC 3164,但严格来说它只是个"观察记录",不是真正的标准。为什么这么说?因为它对消息格式的描述太模糊了——时间戳没有年份,主机名可以随便写,连消息长度都没定义。
我在项目里就吃过这个亏。当时对接一台老交换机,它发出的 Syslog 时间戳只有月和日,跨年日志根本没法排序。后来升级到 RFC 5424,这些问题才彻底解决。
两个版本的核心区别,我列了个表:
| 对比项 | RFC 3164(传统) | RFC 5424(结构化) |
|---|---|---|
| 时间戳格式 | 无年份,如 Oct 11 22:14:15 | ISO 8601,含时区 |
| 主机名字段 | 可选,格式随意 | 非空,FQDN 或 IP |
| 消息长度 | 无限制(实际依赖传输) | 明确限制 2048 字节 |
| 结构化数据 | 不支持 | 支持 key=value |
| 字符编码 | ASCII | UTF-8 |
| 应用场景 | 网络设备、老旧系统 | 现代 IT 系统、云环境 |
2.2 Syslog 消息格式解析
一条完整的 Syslog 消息长什么样?来看我随手从服务器上抓的一条:
<34>1 2024-10-11T22:14:15.123Z myhost.example.com su - - - 'su root' failed for user on /dev/pts/8
这串东西看着乱,拆开就清楚了。我习惯把它分成三块:PRI + HEADER + MSG。
PRI 部分: 尖括号里的数字 34。这个数字由两个值计算得来:设施编号 × 8 + 严重级别。34 反过来推算,就是设施 4(auth 安全认证)乘以 8 等于 32,再加级别 2(critical),正好对上。具体设施和级别的对应关系,下一节会细说。
HEADER 部分: 从版本号开始到主机名结束。RFC 5424 要求必须有版本号(这里是 1),然后是 ISO 8601 时间戳、FQDN 主机名。注意中间那个空的字段——应用名、进程 ID、消息 ID 在 RFC 5424 里是可选字段,没有就用 - 占位。
MSG 部分: 两个 - 之后,全部是消息体。这里记录了一条 sudo 认证失败的详情。
- 占位一定要处理,不能简单按空格分割。
下面这张图把 Syslog 的核心结构串起来了,从日志产生到服务器落地,每个环节都在做什么,一目了然:
2.3 设施级别与严重级别
Syslog 用两个维度给消息分类:谁产生的(设施)和 有多严重(级别)。这两者编码在 PRI 字段里,我习惯把它们背下来,因为排错时经常要用到。
设施(Facility) 标识日志来源。常见的就这几个:
| 代码 | 设施名称 | 典型用途 |
|---|---|---|
| 0 | kern | 内核日志 |
| 1 | user | 用户态应用 |
| 3 | auth | 安全认证 |
| 4 | syslog | Syslog 自身 |
| 7 | news | 网络新闻组 |
| 16-23 | local0 - local7 | 自定义设施(常用) |
严重级别(Severity) 定义了 0 到 7 的递进关系:
| 代码 | 级别名称 | 说明 |
|---|---|---|
| 0 | Emergency | 系统不可用 |
| 1 | Alert | 需要立即处理 |
| 2 | Critical | 严重错误 |
| 3 | Error | 一般错误 |
| 4 | Warning | 警告 |
| 5 | Notice | 正常但重要 |
| 6 | Informational | 信息 |
| 7 | Debug | 调试 |
2.4 Syslog 传输机制
消息格式化好了,怎么把它送到服务器?主要有三种方式。
UDP 514: 最传统的做法。无连接、不确认,发完就算。优点是不占资源,缺点是丢包不重传。我一般在内网、丢几条日志不影响大局的场合用这个。网络设备默认全走 UDP 514,改都改不了。
TCP 6514: 面向连接,保证可达。Syslog 标准里分配的端口是 6514(不是 514)。用 TCP 的好处是消息不会丢,适合对完整性要求高的业务日志。缺点是需要维护连接状态,并发量大了会消耗系统资源。
TLS 加密传输: 在 TCP 基础上加一层 SSL/TLS。我建议所有经过公网的 Syslog 都走 TLS。曾经有个客户把内部日志通过公网传到总部,明文 UDP 跑了两年,直到安全审计才发现问题——中间人随便抓包就能看到所有认证记录。
| 传输方式 | 端口 | 是否可靠 | 是否加密 | 适用场景 |
|---|---|---|---|---|
| UDP | 514 | 否 | 否 | 内网、容忍少量丢失 |
| TCP | 6514 | 是 | 否 | 需可靠送达 |
| TLS | 6514(可配置) | 是 | 是 | 公网、安全合规要求 |
2.5 避坑指南——我的实战经验
讲几个我在工程里实际踩过的坑,你遇到了可以直接绕开。
坑一:消息长度超限被截断。 传统 Syslog 单条消息最大 1024 字节,RFC 5424 放宽到 2048。但很多网络设备出厂配置还是 1024。我遇到过几次,应用报错日志被截断,关键堆栈信息没了。解决办法是在日志源端把消息长度限制调大,或者在收集端设置 MESSAGE_LENGTH 参数。
坑二:时间戳没有时区。 RFC 3164 不要求时区,导致跨机房排错时日志时间对不上。我记得有一次查一个跨国的调用链问题,A 机房和 B 机房的日志差了 8 小时,排查了半天才发现是时区问题。从那以后我强制所有日志源都走 NTP 同步,并且统一使用 UTC 时间。
坑三:设施编号冲突。 local0 到 local7 是留给用户自定义的,但不同应用可能抢同一个编号。比如 Java 应用和 Nginx 插件都用了 local1,日志就混了。我建议你做一个设施编号分配表,写进运维文档,别靠脑子记。
logger 命令手动发一条消息测试链路。比如 logger -p auth.info -n 192.168.1.100 -P 514 "test message",几秒钟就能验证配置是否生效,比看日志文件快多了。
好了,Syslog 协议的基础就这些。消息结构、级别体系、传输机制,这三块搞明白,后面配置 Filebeat 的时候你就能理解为什么有些字段要这样映射、为什么有些传输参数要这样设。这都是环环相扣的东西。