Rsyslog输出Logstash兼容JSON格式异常问题求助
解决Rsyslog生成Logstash兼容JSON时内部引号转义问题
核心问题分析
你遇到的问题本质是Rsyslog默认会将message字段视为普通字符串处理,在生成外层JSON时自动转义其中的引号,导致Logstash无法识别嵌套的JSON结构。以下是两种直接可行的解决思路:
方案1:将内部JSON解析为结构化字段
把自定义脚本输出的JSON解析成Rsyslog的原生结构化属性,直接生成扁平的JSON结构,避免嵌套转义。
配置步骤
- 加载所需模块,包括
mmjsonparse用于解析JSON:
module(load="imrelp") module(load="mmexternal") module(load="mmjsonparse")
- 定义规则集处理RELP输入,解析脚本输出的JSON:
input(type="relp" port="514" ruleset="processRelp") ruleset(name="processRelp") { # 调用自定义处理脚本 action(type="mmexternal" binary="/path/to/your/processing-script") # 将脚本输出的JSON解析为Rsyslog结构化字段(前缀$!) action(type="mmjsonparse" input="msg") # 定义Logstash兼容的JSON模板 template(name="logstashFlatJson" type="list") { constant(value="{") constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339") constant(value="\",") constant(value="\"severity\":\"") property(name="syslogseverity-text") constant(value="\",") constant(value="\"host\":\"") property(name="hostname") constant(value="\",") # 直接引用解析后的自定义字段 constant(value="\"user_id\":\"") property(name="$!user_id") constant(value="\",") constant(value="\"event_type\":\"") property(name="$!event_type") constant(value="\"") constant(value="}") } # 输出到文件(可替换为omrelp直接发送给Logstash) action(type="omfile" file="/var/log/logstash-output.log" template="logstashFlatJson") }
方案2:直接嵌入内部JSON避免转义
如果需要保留嵌套JSON结构,修改模板让Rsyslog直接插入原始JSON内容,不做转义处理。
配置步骤
- 基础模块与输入配置:
module(load="imrelp") module(load="mmexternal") input(type="relp" port="514" ruleset="processRelp")
- 定义模板时使用
json-nofilter格式,跳过字符串转义:
ruleset(name="processRelp") { action(type="mmexternal" binary="/path/to/your/processing-script") template(name="logstashNestedJson" type="list") { constant(value="{") constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339") constant(value="\",") constant(value="\"severity\":\"") property(name="syslogseverity-text") constant(value="\",") constant(value="\"host\":\"") property(name="hostname") constant(value="\",") # 直接插入原始JSON内容,不转义 constant(value="\"message_details\":") property(name="msg" format="json-nofilter") constant(value="}") } action(type="omfile" file="/var/log/logstash-nested.log" template="logstashNestedJson") }
- 对应的Logstash过滤器配置(解析嵌套JSON):
filter { json { source => "message_details" remove_field => "message_details" # 解析完成后可移除原字段 } }
关键注意事项
- 确保自定义脚本输出纯合法的JSON字符串,无多余换行、空格或非JSON内容
- 用
jq工具验证输出的JSON格式:jq . /var/log/logstash-output.log - 若
json-nofilter不生效(老版本Rsyslog),改用字符串模板直接拼接:
template(name="logstashNestedJson" type="string" string="{\"@timestamp\":\"%timereported:::rfc3339%\",\"severity\":\"%syslogseverity-text%\",\"host\":\"%hostname%\",\"message_details\":%msg%}")
内容的提问来源于stack exchange,提问作者Sean Lennon
相关产品推荐
相关产品推荐

