6. Syslog 消息格式 (Syslog Message Format)
syslog 消息具有以下 ABNF 定义:
SYSLOG-MSG = HEADER SP STRUCTURED-DATA [SP MSG]
HEADER = PRI VERSION SP TIMESTAMP SP HOSTNAME
SP APP-NAME SP PROCID SP MSGID
PRI = "<" PRIVAL ">"
PRIVAL = 1*3DIGIT ; range 0 .. 191
VERSION = NONZERO-DIGIT 0*2DIGIT
HOSTNAME = NILVALUE / 1*255PRINTUSASCII
APP-NAME = NILVALUE / 1*48PRINTUSASCII
PROCID = NILVALUE / 1*128PRINTUSASCII
MSGID = NILVALUE / 1*32PRINTUSASCII
TIMESTAMP = NILVALUE / FULL-DATE "T" FULL-TIME
FULL-DATE = DATE-FULLYEAR "-" DATE-MONTH "-" DATE-MDAY
DATE-FULLYEAR = 4DIGIT
DATE-MONTH = 2DIGIT ; 01-12
DATE-MDAY = 2DIGIT ; 01-28, 01-29, 01-30, 01-31
FULL-TIME = PARTIAL-TIME TIME-OFFSET
PARTIAL-TIME = TIME-HOUR ":" TIME-MINUTE ":" TIME-SECOND
[TIME-SECFRAC]
TIME-HOUR = 2DIGIT ; 00-23
TIME-MINUTE = 2DIGIT ; 00-59
TIME-SECOND = 2DIGIT ; 00-59
TIME-SECFRAC = "." 1*6DIGIT
TIME-OFFSET = "Z" / TIME-NUMOFFSET
TIME-NUMOFFSET = ("+" / "-") TIME-HOUR ":" TIME-MINUTE
STRUCTURED-DATA = NILVALUE / 1*SD-ELEMENT
SD-ELEMENT = "[" SD-ID *(SP SD-PARAM) "]"
SD-PARAM = PARAM-NAME "=" %d34 PARAM-VALUE %d34
SD-ID = SD-NAME
PARAM-NAME = SD-NAME
PARAM-VALUE = UTF-8-STRING
SD-NAME = 1*32PRINTUSASCII
MSG = MSG-ANY / MSG-UTF8
MSG-ANY = *OCTET
MSG-UTF8 = BOM UTF-8-STRING
BOM = %xEF.BB.BF
UTF-8-STRING = *OCTET
OCTET = %d00-255
SP = %d32
PRINTUSASCII = %d33-126
NONZERO-DIGIT = %d49-57
DIGIT = %d48 / NONZERO-DIGIT
NILVALUE = "-"
消息由以下部分组成:
- HEADER: 包含关于消息的元数据 (优先级,版本,时间戳,源信息)
- STRUCTURED-DATA: 可选的名称-值对形式的结构化信息
- MSG: 可选的自由格式消息内容
6.1. 消息长度 (Message Length)
对于 UDP 传输,Syslog 消息不得超过 480 字节.这确保了与有限网络实现的兼容性.
Syslog 接收方必须能够接受最多 480 字节的消息.接收方应能够接受最多 2048 字节的消息.
Syslog 发送方可以发送超过 480 字节的消息.但是,如果需要,它们应实现消息截断或拆分机制.
传输映射可以指定不同的最大消息大小.例如,TLS 传输通常允许更大的消息.
消息长度以字节而非字符测量.UTF-8 编码可能导致每个字符有多个字节.
6.2. HEADER (报文头)
HEADER 按以下确切顺序包含以下字段:
6.2.1. PRI (优先级)
PRI 部分包含用尖括号括起来的优先级值.优先级值由 Facility (设施) 和 Severity (严重性) 值计算:
Priority = Facility * 8 + Severity
Facility 值:
| 值 | Facility |
|---|---|
| 0 | 内核消息 |
| 1 | 用户级消息 |
| 2 | 邮件系统 |
| 3 | 系统守护进程 |
| 4 | 安全/授权消息 |
| 5 | syslogd 内部生成的消息 |
| 6 | 行式打印机子系统 |
| 7 | 网络新闻子系统 |
| 8 | UUCP 子系统 |
| 9 | 时钟守护进程 |
| 10 | 安全/授权消息 |
| 11 | FTP 守护进程 |
| 12 | NTP 子系统 |
| 13 | 日志审计 |
| 14 | 日志警报 |
| 15 | 时钟守护进程 |
| 16-23 | 本地使用 0-7 (local0 - local7) |
Severity 值:
| 值 | Severity | 描述 |
|---|---|---|
| 0 | Emergency | 系统不可用 |
| 1 | Alert | 必须立即采取行动 |
| 2 | Critical | 危急情况 |
| 3 | Error | 错误情况 |
| 4 | Warning | 警告情况 |
| 5 | Notice | 正常但重要的情况 |
| 6 | Informational | 信息性消息 |
| 7 | Debug | 调试级消息 |
示例: Facility 4 (安全/授权) 和 Severity 2 (Critical) 的消息优先级值为:
Priority = 4 * 8 + 2 = 34
PRI = "<34>"
PRI 值必须在 0 到 191 之间.
6.2.2. VERSION (版本)
VERSION 字段表示 syslog 协议的版本.本文档定义版本 1.VERSION 值必须是 1-999 范围内的非零整数.
6.2.3. TIMESTAMP (时间戳)
TIMESTAMP 字段是指示消息生成时间的格式化时间戳.它应表示所描述事件发生的时间.
时间戳格式基于 RFC 3339,有以下要求:
- 日期格式 YYYY-MM-DD
- 时间分隔符 "T"
- 时间格式 HH:MM:SS (24 小时制)
- 可选的秒小数部分 (最多 6 位数字)
- 时区偏移 (UTC 用 "Z" 或 "+/-HH:MM")
示例:
2003-10-11T22:14:15.003Z
2003-08-24T05:14:15.000003-07:00
2009-03-12T18:53:01+00:00
如果发起者不知道时间,则必须使用 NILVALUE ("-").
最佳实践:
- 尽可能使用 UTC 时区 (Z) 以保持一致性
- 当精度重要时包含秒小数部分
- 确保时间同步 (NTP) 以获得准确的时间戳
6.2.4. HOSTNAME (主机名)
HOSTNAME 字段标识最初生成 syslog 消息的机器.它应包含以下之一:
- 完全限定域名 (FQDN) - 推荐
- 静态 IP 地址
- 主机名
- 动态 IP 地址
- NILVALUE ("-") 如果未知
推荐使用 FQDN 格式,因为它提供最准确的标识.
如果使用 IPv6 地址,应将其括在方括号中.
最大长度: 255 个 ASCII 可打印字符.
6.2.5. APP-NAME (应用名称)
APP-NAME 字段标识生成消息的设备或应用程序.它是一个不带空格的自由格式字符串.
示例:
myapp
su
postfix/smtpd
最大长度: 48 个 ASCII 可打印字符.
如果 APP-NAME 未知,使用 NILVALUE ("-").
6.2.6. PROCID (进程ID)
PROCID 字段是每次启动或重启进程时更改的值.它通常包含:
- Unix 类系统上的进程 ID (PID)
- 线程 ID
- 进程名称
- 其他唯一标识符
示例:
12345
thread1
-
最大长度: 128 个 ASCII 可打印字符.
如果不使用 PROCID,设置为 NILVALUE ("-").
6.2.7. MSGID (消息ID)
MSGID 字段标识消息的类型.它是一个不带空格的自由格式字符串,可用于自动解析和路由.
示例:
ID47
TCPIN
login-failure
config-change
最大长度: 32 个 ASCII 可打印字符.
如果不使用 MSGID,设置为 NILVALUE ("-").
6.3. STRUCTURED-DATA (结构化数据)
STRUCTURED-DATA 提供了一种以结构化,易于解析的格式表达信息的机制.它由一个或多个 SD-ELEMENT 组成.
6.3.1. SD-ELEMENT (结构化数据元素)
SD-ELEMENT 由以下部分组成:
- SD-ID (标识符)
- 零个或多个 SD-PARAM (参数)
格式: [SD-ID PARAM1="value1" PARAM2="value2" ...]
6.3.2. SD-ID (结构化数据标识符)
SD-ID 唯一标识元素的类型和目的.
IANA 注册的 SD-ID: 由可打印 ASCII 字符组成,不包括 =,]," 和空格.
私有企业 SD-ID: 必须采用格式 name@<private enterprise number>,其中企业编号在 IANA 注册.
示例:
timeQuality
origin
myCompany@32473
6.3.3. SD-PARAM (结构化数据参数)
每个 SD-PARAM 是一个名称-值对:
PARAM-NAME="PARAM-VALUE"
PARAM-VALUE 必须使用 UTF-8 编码.特殊字符必须转义:
"变为\"\变为\\]变为\]
示例:
[exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"]
允许对同一参数名称重复多个值:
[example ip="192.0.2.1" ip="192.0.2.2"]
6.3.4. 变更控制 (Change Control)
可以通过 IANA 注册新的 SD-ID.详见第 9 节.
私有企业可以使用其注册的企业编号创建私有 SD-ID 而无需注册.
6.3.5. 示例
单个 SD-ELEMENT:
[exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"]
多个 SD-ELEMENT:
[exampleSDID@32473 iut="3"][examplePriority@32473 class="high"]
无结构化数据:
-
6.4. MSG (消息体)
MSG 部分包含自由格式的消息文本.它有两种可能的格式:
- MSG-ANY: 任意字节序列
- MSG-UTF8: 带 BOM 前缀的 UTF-8 字符串 (字节顺序标记: 0xEF 0xBB 0xBF)
如果 MSG 以 UTF-8 BOM 开头,收集器或中继应假设 MSG 以 UTF-8 编码.否则,编码未指定.
MSG 部分是可选的.如果不存在,消息结尾前不加 SP.
最佳实践:
- 使用带 BOM 的 UTF-8 编码以实现一致的国际字符支持
- 避免包含换行符或其他控制字符
- 将重要信息保留在消息早期 (前 480 字节内)
6.5. 示例
示例 1: 包含所有字段和结构化数据的完整消息
<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"] BOMsystem crashed
示例 2: 包含 NILVALUE 字段的消息
<165>1 2003-08-24T05:14:15.000003-07:00 192.0.2.1 myproc 8710 - - %% It's time to make the do-nuts.
示例 3: 包含 UTF-8 内容和多个 SD-ELEMENT 的消息
<165>1 2003-10-11T22:14:15.003Z mymachine.example.com evntslog - ID47 [exampleSDID@32473 iut="3" eventSource="Application" eventID="1011"][examplePriority@32473 class="high"] BOMAn application event log entry...
示例 4: 最小消息 (紧急内核消息)
<0>1 2009-03-12T18:53:01+00:00 server1 kernel - - - System will shutdown