Linux之rsyslog(4)属性配置
Linux之rsyslog(4)属性配置
Author:Once Day Date:2025年11月7日
全系列文章请查看专栏: Linux Shell基础_Once_day的博客-CSDN博客。
漫漫长路,有人对你微笑过嘛…
参考文档:
- Beginner Tutorials - rsyslog 8.2510.0 documentation
1. 属性配置
rsyslog 中的数据项称为 “属性”,来源多样。最重要的属性来自接收的消息,此外还有其他类型。访问任何数据项都需通过对应的属性进行。
属性的使用场景:
- 模板(templates)
- 条件语句(conditional statements)
属性名称不区分大小写(3.17.0 版本前区分大小写),文档描述和示例中建议使用标题栏的拼写形式。
1.1 消息属性(Message Properties)
这类属性由 rsyslog 解析器从原始消息中提取,所有消息属性均以字母开头。
| 属性 | 概述 |
|---|---|
| msg | 返回处理后 syslog 消息的 MSG 部分。 |
| rawmsg | 提供 rsyslog 接收消息时的原始存储内容。 |
| rawmsg-after-pri | 包含去除 syslog PRI 头部(若存在)后的原始消息内容。 |
| hostname | 捕获 syslog 消息中传输的主机名。 |
| source | 与 hostname 返回相同的主机名值。 |
| fromhost | 报告接收消息的系统主机名。 |
| fromhost-ip | 与 fromhost 类似,以 IP 地址形式提供消息来源。 |
| fromhost-port | 与 fromhost 对应,报告发送方的数字源端口。 |
| syslogtag | 返回从 syslog 消息头部提取的 TAG 字段。 |
| programname | 从 syslog 标签中提取静态程序名部分。 |
| pri | 提供 RFC 5424 第 6.2.1 节定义的未解码 PRI 头部值。 |
| pri-text | 将 RFC 5424 PRI 头部格式化为 “facility.severity” 形式,并附加数字 PRI 值。 |
| iut | 存储存在的 monitorware InfoUnitType 值。 |
| syslogfacility | 包含从消息中提取的数字形式 syslog 设备值。 |
| syslogfacility-text | 返回 RFC 5424 表 1 中定义的文本形式 syslog 设备名。 |
| syslogseverity | 包含从消息中提取的数字形式 syslog 级别值。 |
| syslogseverity-text | 返回 RFC 5424 表 2 中定义的文本形式 syslog 级别名。 |
| syslogpriority | 因历史原因,与 syslogseverity 返回相同的数字值。 |
| syslogpriority-text | 与 syslogseverity-text 返回相同的文本级别字符串。 |
| timegenerated | 高精度记录 rsyslog 接收消息的时间。 |
| timereported | 捕获原始消息头部中存在的时间戳。 |
| timestamp | 与消息头部的 timereported 返回相同值。 |
| protocol-version | 承载 RFC 5424 第 6.2.2 节定义的 VERSION 头部字段。 |
| structured-data | 提供 RFC 5424 第 6.3 节定义的 STRUCTURED-DATA 字段。 |
| app-name | 承载 RFC 5424 第 6.2.5 节定义的 APP-NAME 头部字段。 |
| procid | 承载 RFC 5424 第 6.2.6 节定义的 PROCID 头部字段。 |
| msgid | 承载 RFC 5424 第 6.2.7 节定义的 MSGID 头部字段。 |
| inputname | 标识生成该消息的 rsyslog 输入模块实例。 |
| uuid | 启用后,首次访问时生成并暴露每条消息的唯一标识符(UUID)。 |
| jsonmesg | 以 JSON 格式提供整个消息对象。 |
1.2 系统属性(System Properties)
这类属性由 rsyslog 核心引擎提供,与消息无关。所有系统属性均以美元符号($)开头。
时间相关系统变量的特别说明:
timereported:包含消息头部的时间戳,理论上对应消息在原始发送端创建的时间。消息在转发链中传输的时间越长,该时间戳可能越旧。timegenerated:记录本地系统接收消息的时间。这里的 “接收” 指消息从操作系统移交至 rsyslog 接收缓冲区的时间,早于任何实际处理流程,且早于进入队列的时间。需注意,部分输入模块可能会对接收缓冲区中的消息进行提取内容等最小化处理。若多条消息通过同一接收缓冲区接收(如 TCP syslog 的常见场景),它们的timegenerated值相同,因为实际接收时间一致。$now:与消息无关,指消息被处理时的系统时间。timegenerated与$now始终存在微小差异,因为处理总是在接收之后。若消息在本地队列中等待,两者的差异可能为几秒(如消息突发导致内存队列积压),极端情况下(如数据库故障导致磁盘队列积压)可达数小时。timereported通常早于timegenerated,但受不同系统时间和时区配置影响,两者可能差异极大。
系统属性列表:
| 属性 | 概述 |
|---|---|
| $bom | 生成 UTF-8 字节顺序标记(BOM),适用于模板中需要 BOM 的场景。 |
| $myhostname | 返回 rsyslog 识别的本地主机名。 |
1.3 时间相关系统属性
所有时间相关系统属性均提供本地时间版本(如$now)和 UTC 时间版本(如$now-utc)。UTC 版本可通过在属性名后添加 “-utc” 获取。
单个模板中应仅使用本地时间或 UTC 时间一种版本。虽然混合使用语法上允许,但无法保证时间的精确一致性。技术原因是 rsyslog 切换版本时需重新查询系统时间。强烈建议不要在同一模板中混合两种版本。
不同模板中使用不同版本时,每个模板内部的时间戳保持一致。但$now始终返回使用时的本地系统时间,若时间推进,不同模板的时间戳可能不同。如需避免此问题,建议使用timegenerated。
| 属性 | 概述 |
|---|---|
| $now | 返回消息处理时的当前本地日期时间戳。 |
| $year | 返回 4 位数字表示的当前年份。 |
| $month | 返回 2 位数字表示的当前月份。 |
| $day | 返回 2 位数字表示的当前日期(月内天数)。 |
| $wday | 返回 gmtime () 定义的当前星期几数字(0 = 周日,6 = 周六)。 |
| $hour | 返回 24 小时制的当前小时数。 |
| $hhour | 指示当前分钟处于小时的前半段(0-29 分)还是后半段(30-59 分)。 |
| $qhour | 指示当前小时内的一刻钟(0=0-14 分,1=15-29 分,2=30-44 分,3=45-59 分)。 |
| $minute | 返回 2 位数字表示的当前分钟数。 |
| $now-unixtimestamp | 以单调递增的 Unix 时间戳形式返回当前时间。 |
2. 属性替换(The Property Replacer)
属性替换器是 rsyslogd 字符串模板系统的核心组件。syslog 消息包含多个预定义属性,属性替换器可访问并处理这些属性,轻松截取属性值的部分内容或进行修改(如转换为小写)。
2.1 属性使用
syslog 消息属性在模板中使用,需放在百分号(%)之间。属性可通过属性替换器修改,完整语法如下:
%property:fromChar:toChar:options%
属性替换器可使用所有 rsyslog 属性(包括消息属性和系统属性)。
fromChar和toChar用于截取子字符串,指定字符串中需复制的偏移位置,计数从 1 开始。
- 示例 1:获取消息文本的前 2 个字符 →
%msg:1:2%。 - 示例 2:不指定位置但需设置选项,需保留冒号 → 转换消息为小写 →
%msg:::lowercase%。 - 示例 3:从指定位置截取至字符串末尾,
toChar设为$→ 从第 10 位截取至末尾 →%msg:10:$%。
使用正则表达式时,fromChar需设为R,表示采用正则提取而非位置提取。正则表达式需放在toChar中,且以--end结尾(标识正则结束,不包含在表达式内)。
- 示例:提取消息中匹配
Sev:. \(.*\) \[.*的部分 →%msg:R:.*Sev:. \(.*\) \[.*--end%。
正则参数(逗号分隔),格式:R,<regexp-type>,<submatch>,<nomatch>,<match-number>:
regexp-type:正则类型,BRE(基础正则,默认)或ERE(扩展正则),需大写。submatch:子匹配项,0 为完整匹配,1-9 为子匹配。nomatch:无匹配时的替代内容。match-number:匹配序号(多个匹配时),0 为第一个匹配,1 为第二个,最多支持 9 个。
正则示例:
- ERE 表达式,提取第一个子匹配,无匹配时显示
FIELD→%msg:R,ERE,1,FIELD:for (vlan[0-9]*):--end%。 - 提取第二个匹配的第一个子匹配 →
%msg:R,ERE,1,FIELD,1:for (vlan[0-9]*):--end%。
可使用 rsyslog 在线正则检查器 / 生成器验证表达式,工具适用于常见场景,复杂需求需手动编写。
按字段提取时,fromChar需设为F,字段默认以制表符(ASCII 9)分隔,可通过F,<ASCII值>指定其他分隔符(ASCII 十进制值)。
- 字段计数从 1 开始,0 或超出字段总数会返回 “字段未找到” 错误。
- 示例 1:提取
msg的第 3 个制表符分隔字段 →%msg:F:3%。 - 示例 2:以分号(ASCII 59)为分隔符,提取第 3 个字段 →
%msg:F,59:3%。
字段子字符串提取,字段提取可附加fromPos(起始位置)和toPos(结束位置),语法较特殊:
- 示例:以分号为分隔符,提取第 3 个字段的第 5-9 位字符 →
%msg:F,59,5:3,9%(F,59= 分号分隔,,5= 起始位置 5;3= 第 3 个字段,,9= 结束位置 9) 。
多分隔符处理,分隔符后加+,可将连续分隔符视为独立字段(模仿 Perl 正则):
- 示例:以空格(ASCII 32)为分隔符,处理连续空格 →
%msg:F,32+:2%。
注意事项:
F和R区分大小写,仅大写有效,小写会报错。- 语法序列中不允许空格,否则会报错且无法达到预期效果。
2.2 属性选项(Property Options)
属性选项不区分大小写,目前支持以下选项:
(1)文本大小写转换:
- uppercase:仅将属性值转换为大写。
- lowercase:仅将属性值转换为小写。
(2)字符串格式调整:
- fixed-width:修改
toChar的行为,若源字符串长度短于toChar指定值,用空格填充至该长度(rsyslog 8.13.0 版本引入)。 - compressspace:将字符串内多个连续空格(ASCII 空格字符)压缩为单个空格,处理阶段极晚,不影响
fromChar和toChar指定的子字符串截取位置(v8.18.0 版本引入)。 - drop-last-lf:去除消息末尾的换行符(若存在),对 PIX 设备日志尤为实用。
(3)编码与格式标准化:
- json:对值进行编码,使其可用于 JSON 字段(按 JSON 规范转义特殊字符,如 ASCII 换行符转为
\n),不可与jsonf或csv选项同时使用。 - jsonf[:outname]:将属性表示为完整 JSON 字段(格式:
"fieldname":"value"),fieldname为outname指定值(未指定则用属性名),值支持所有属性替换器选项且自动 JSON 转义(字段名暂不转义),不可与json或csv选项同时使用。 - csv:按 RFC 4180 规范将处理后的字段格式化为 CSV 格式,始终使用双引号包裹,需在模板中手动添加字段间的逗号。
(4)日期格式:
- date-utc:输出日期前转换为 UTC 时间(8.18.0 版本起支持)。
- date-mysql:格式化为 MariaDB/MySQL 兼容日期。
- date-rfc3164:格式化为 RFC 3164 标准日期。
- date-rfc3164-buggyday:类似
date-rfc3164,但单 digit 日期前补 0(而非空格),用于兼容 syslog-ng 等存在该编码错误的场景,不建议转发至远程主机(可能被视为无效日期)(4.6.2、5.5.3 及以上版本引入)。 - date-rfc3339:格式化为 RFC 3339 标准日期。
- date-unixtimestamp:格式化为 Unix 时间戳(自纪元起的秒数)。
- date-year:仅返回时间戳的 4 位年份部分。
- date-month:仅返回时间戳的 2 位月份部分。
- date-day:仅返回时间戳的 2 位日期部分。
- date-hour:仅返回时间戳的 24 小时制 2 位小时部分。
- date-minute:仅返回时间戳的 2 位分钟部分。
- date-second:仅返回时间戳的 2 位秒数部分。
- date-subseconds:仅返回时间戳的亚秒部分(低精度时间戳始终为 0)。
- date-tzoffshour:仅返回时间戳的 2 位时区偏移小时部分。
- date-tzoffsmin:仅返回时间戳的 2 位时区偏移分钟部分(通常为 0,非整小时偏移时区适用)。
- date-tzoffsdirection:仅返回时间戳的时区偏移方向(
+表示需加偏移得到 UTC,-表示需减偏移)。 - date-ordinal:返回日期在当年的序数(如 1 月 2 日返回 2)。
- date-iso-week / date-iso-week-year:分别返回 ISO 周数和 ISO 周所属年份,需搭配使用。
- date-week:返回周数。
- date-wday:仅返回时间戳的星期数字(1 位,0 = 周日,1 = 周一,…,6 = 周六)。
- date-wdayname:仅返回时间戳的英文缩写星期名(如 “Mon”“Sat”)。
控制字符处理(需将$EscapeControlCharactersOnReceive设为off):
- escape-cc:将控制字符(ASCII 0-31、127)替换为转义序列
#<charval>(charval为 3 位十进制 ASCII 值,如制表符转为#009)。 - space-cc:将控制字符替换为空格。
- drop-cc:丢弃控制字符,结果字符串中不包含控制字符、转义序列或替换字符。
特殊功能:
- sp-if-no-1st-sp:仅返回单个空格或空字符(不返回字段内容),字段首字符非空格时返回空格,用于解决 RFC 3164 中标签与消息无分隔符的兼容问题,普通用户无需使用。
- secpath-drop:删除字段中的斜杠(如 “a/b” 变为 “ab”),适用于动态文件的安全路径生成。
- secpath-replace:将字段中的斜杠替换为下划线(如 “a/b” 变为 “a_b”),适用于动态文件的安全路径生成。
多个选项可通过逗号分隔叠加使用(如escape-cc,sp-if-no-1st-sp)。选项冲突时,后指定的选项覆盖前一个(如escape-cc,drop-cc最终生效drop-cc)。
2.3 属性替换器无匹配模式(Property Replacer nomatch mode)
“无匹配模式(nomatch-Mode)” 指定正则表达式未找到搜索字符串时,属性替换器返回的内容。传统上返回字符串 “NO MATCH”,但因实用性极低,该模式保留为 “DFLT” 以兼容旧配置。
目前新增三种更实用的模式,满足不同场景需求:
- BLANK:返回空字符串,适用于数据库插入场景,无匹配时不插入值。
- ZERO:返回字符串 “0”,适合数值类型字段,例如防火墙流量日志中 “传输字节数” 无匹配时,可返回 “0” 供数据库处理。
- FIELD:返回原始字段的完整内容,适用于将无匹配视为异常、需保留原始消息进行排查的场景。
若有疑问,建议使用 rsyslog 在线正则表达式检查器和生成器,通过样本测试不同模式的效果,快速调试正则表达式。
无匹配模式汇总:
| 模式 | 返回内容 |
|---|---|
| DFLT | “NO MATCH”(默认兼容) |
| BLANK | 空字符串(“”) |
| ZERO | 字符串 “0” |
| FIELD | 原始字段的完整内容 |
