Rsyslog v8.32+ 的 Expression-Based 过滤器使用 property 表达式(如 $msg、$programname)配合 ==、contains、regex 等操作符及 && || ! 布尔逻辑实现精准日志路由,需启用新版解析器并推荐结合 mmjsonparse 等模块进行结构化字段匹配。

Rsyslog 的 Expression-Based 过滤器(基于表达式的过滤器)是 v8.32+ 版本引入的现代语法,替代了传统 `$programname ==` 或 `if $msg contains` 等旧式写法,支持更清晰、可读性更强、逻辑更严谨的日志内容分拣。核心在于使用 property-based 表达式 + 布尔逻辑 + 字符串/正则匹配操作符,直接在 if 条件中完成日志字段的判断与路由。
确认 Rsyslog 版本并启用新语法
Expression-Based 过滤器依赖 rsyslog 的“improved parser”,需确保版本 ≥ 8.32(推荐 ≥ 8.40),且配置中启用新语法解析器:
- 检查版本:
rsyslogd -v | head -1 - 确保主配置(如
/etc/rsyslog.conf)顶部包含:$ActionFileDefaultTemplate RSYSLOG_ForwardFormat$EscapeControlCharactersOnReceive off(避免转义干扰内容匹配) - 显式启用新语法(v8.34+ 默认开启,但建议显式声明):
module(load="impstats" interval="600")module(load="builtin:omfile")module(load="builtin:omfwd")
——这些模块加载本身即激活新版 parser
用 property 和 operator 构建精准匹配条件
所有日志字段都作为 property 可被引用,常用 property 包括:$msg(原始消息体)、$programname(进程名)、$syslogtag、$hostname、$timestamp 等。配合操作符实现逻辑分拣:
-
==/!=:精确字符串匹配(区分大小写) -
contains:子串存在(如$msg contains "ERROR") -
startswith/endswith:前缀/后缀匹配 -
regex:PCRE 正则匹配(需module(load="mmnormalize")或启用 PCRE 支持;v8.35+ 内置) - 布尔组合:
&&(且)、||(或)、!(非),支持括号分组
示例:将含 “Failed password” 且来源不是 “192.168.1.100” 的 SSH 登录失败日志单独存入文件:
if $programname == 'sshd' && $msg contains 'Failed password' && $fromhost-ip != '192.168.1.100' then /var/log/auth-failed-external.log
按业务语义拆分应用日志(多级 if-else 路由)
真实场景常需多条件嵌套分拣。Rsyslog 支持 if ... then { ... } else if ... then { ... } else { ... } 结构,避免重复解析、提升效率:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 每个
if块只对满足条件的日志执行动作,不匹配则跳过 - 动作可为写文件、转发、丢弃(
stop)、调用模板等 - 务必用
stop阻止后续规则匹配(否则可能被其他通用规则二次处理)
示例:对某 Java 应用(appname="order-service")的日志按错误等级分流:
if $programname == 'order-service' then {
if $msg contains 'FATAL' then {
action(type="omfile" file="/var/log/order/fatal.log")
stop
}
if $msg contains 'ERROR' && !($msg contains 'timeout') then {
action(type="omfile" file="/var/log/order/error.log")
stop
}
if $msg regex 'INFO.*payment.*success' then {
action(type="omfile" file="/var/log/order/payment-success.log")
stop
}
action(type="omfile" file="/var/log/order/other.log")
}结合模板(template)增强结构化分拣能力
单纯靠 $msg 匹配易受格式变化影响。推荐先用 mmnormalize 或 mmjsonparse 提取结构化字段,再基于提取出的 key 做判断:
- 若日志为 JSON 格式(如 Spring Boot 的
logging.pattern.console设为 JSON),加载mmjsonparse模块 - 解析后,可用
$!level、$!service、$!.exception等字段直接参与判断 - 避免正则硬解析,提升稳定性和性能
示例(需提前加载 module(load="mmjsonparse")):
if $!level == "ERROR" && $!service == "user-api" && $!.exception != "" then {
action(type="omfile" file="/var/log/user-api/exception.log")
stop
}










