最有效的方式是在rsyslog接收日志第一时间用rainerscript的re_replace()清洗$msg并覆盖写回;需rsyslog v8.33+,通过if+set精准定位、链式替换敏感字段,再用洁净$msg输出至文件模板,上线前须验证正则与性能。

最有效的方式是在 rsyslog 接收日志的第一时间,用 RainerScript 的 re_replace() 对原始消息字段 $msg 做正则清洗,再覆盖写回——这能确保所有路径(包括异常日志、调试输出、旧版应用)中的敏感内容都被统一擦除,不依赖上游应用是否“自觉脱敏”。
确认rsyslog版本支持脚本脱敏能力
脱敏功能依赖 rsyslog v8.33 及以上版本,低版本(如 CentOS 7 默认的 8.24)不支持 re_replace() 和动态变量赋值。需执行以下命令验证:
-
rsyslogd -v查看实际版本 - 若低于 8.33,建议通过 EPEL 源升级,或从源码编译安装新版
- 旧版仅支持模板级静态替换(如
%msg:R,REPLACE:...),无法处理 token=abc123、id_card=110101199001011234 这类动态值
在ruleset中用if+set完成精准定位与清洗
脱敏逻辑必须放在条件判断之后、落盘动作之前,且作用于 $msg 字段本身。典型结构如下:
- 用
if $programname == 'app-backend' or $msg contains 'user_id='锁定目标日志流 - 调用
set $!sanitized = re_replace($msg, 'token=[^&\s]+', 'token=***'); - 再执行
set $msg = $!sanitized;覆盖原始消息($!xxx是用户自定义变量,必须以$!开头) - 可链式叠加多条
re_replace(),例如同时处理手机号phone=1[3-9]\d{9}、身份证号id_card=\d{17}[\dXx]
绑定脱敏后消息到文件模板并落地
清洗完成后,$msg 已是洁净内容,后续只需按常规方式输出:
- 定义模板时直接引用
property(name="msg"),无需二次处理 - 示例模板:
template(name="CleanLog" type="list") { property(name="timestamp") constant(" ") property(name="hostname") constant(" ") property(name="msg") } - 规则中调用:
*.* action(type="omfile" file="/var/log/clean/app.log" template="CleanLog") - 切勿在模板里对
%msg%做REPLACE或其他修饰——此时脱敏早已失效
上线前务必验证正则逻辑与性能影响
测试环节不可跳过,否则可能漏脱敏或引入 regex 错误导致日志丢失:
- 用
logger "POST /login HTTP/1.1 User-Agent: curl token=xyz789 phone=13800138000"发送测试日志 - 检查目标文件是否输出为
POST /login... token=*** phone=*** - 运行
journalctl -u rsyslog | grep "re_replace",确认无invalid regex报错 - 单条日志脱敏耗时在微秒级,实测对万级 EPS 吞吐无明显延迟











