Rsyslog如何解析JSON格式日志并在if条件判断中使用解析变量
实现方案
首先明确:该需求完全可实现,无需依赖mmnormalize,仅用mmjsonparse模块即可完成嵌套JSON的解析和字段判断,90%的配置失败问题都来自mmjsonparse的默认参数限制、UDP接收时的消息字段匹配错误。
第一步:加载必要模块
在rsyslog配置文件(通常是/etc/rsyslog.conf或/etc/rsyslog.d/下的自定义conf文件)开头加载UDP接收和JSON解析模块:
module(load="imudp") module(load="mmjsonparse")
第二步:配置UDP监听与解析规则
根据应用发送日志的形式分两种场景配置:
场景1:应用直接裸发JSON(无标准syslog头)
如果应用发UDP包时直接把JSON串作为payload,没有加syslog协议要求的PRI、时间、主机名等前缀,用如下配置:
# 假设日志发送到本地514端口,绑定到JSON日志处理规则集 input(type="imudp" port="514" ruleset="json_log_process") ruleset(name="json_log_process") { # 核心配置:cookie设为空,关闭默认的CEE头校验,直接解析原始UDP消息 action(type="mmjsonparse" cookie="") # 直接使用解析后的嵌套字段做判断,和预期写法完全一致 if ($!http!status_code >= 400) then { action(type="omfile" file="/var/log/haproxy/haproxy-traffic-error.log") stop } # 其余非错误日志可走默认输出规则 *.* /var/log/messages }
场景2:应用按标准syslog格式发送,JSON在消息体中
如果应用发的日志符合syslog格式,JSON串存在$msg字段中(即日志格式类似<134>Oct 10 12:00:00 myapp {"http":{"status_code":400}}),只需要修改mmjsonparse的source参数,指定从msg字段提取JSON解析即可:
ruleset(name="json_log_process") { # 指定从msg字段解析JSON,同样关闭CEE头校验 action(type="mmjsonparse" source="msg" cookie="") # 后续判断逻辑完全不变 if ($!http!status_code >= 400) then { action(type="omfile" file="/var/log/haproxy/haproxy-traffic-error.log") stop } *.* /var/log/messages }
常见踩坑排查
- 最高发问题:
mmjsonparse默认要求待解析的内容开头必须带@cee:标记才会执行解析,如果你发的是裸JSON,必须显式配置cookie=""关闭这个校验,否则解析根本不会触发,$!路径下永远拿不到字段。 - 解析不生效时可以临时加调试规则,把解析后的全量变量打出来定位问题:
发测试日志后查看该文件,能看到所有# 加在mmjsonparse动作之后,所有判断逻辑之前 *.* /tmp/rsyslog_debug.log;RSYSLOG_DebugFormat$!开头的解析字段,如果没有http相关字段,说明解析步骤没拿到正确的JSON内容。 - 测试时可以直接用nc发模拟日志验证配置:
配置生效的话,这条日志会直接写入指定的错误日志文件,不会落到其他默认日志路径。echo '{"http": {"status_code": 403}}' | nc -u 127.0.0.1 514 - 尽量使用上面的RainerScript格式配置,不要用legacy风格的
$ModLoad、$mmjsonparseCookie老写法,避免参数不生效,rsyslog 8.0及以上版本全支持上述配置,目前主流Linux发行版自带的rsyslog版本均满足要求。
内容的提问来源于stack exchange,提问作者Jinsoo Heo
相关产品推荐
相关产品推荐

