为何rsyslog通过TCP转发时无法用JSON模板解析syslog?
TCP模式下RSyslog转发JSON模板失效的排查与解决
我之前碰到过一模一样的问题——UDP转发能正常解析所有字段,TCP就不行,折腾了一阵才找到根因,咱们一步步来解决:
核心原因分析
RSyslog的TCP输出默认采用Octet-Counting格式(每条消息前会加上消息长度的数值),而Logstash的TCP输入默认期望的是换行分隔的文本消息。这种格式不匹配,会导致Logstash无法正确拆分和解析RSyslog发送的JSON内容,看起来就像“无法解析有效信息”。而UDP是无连接的,每条消息天然是独立的,所以不会有这个问题。
解决方案
1. 调整RSyslog的TCP输出格式为换行分隔
把你当前在/etc/rsyslog.conf里的TCP转发配置替换为更明确的action配置,强制使用换行分隔消息:
# 替换原来的*.* @@127.0.0.1:10514;json-template action(type="omfwd" target="127.0.0.1" port="10514" protocol="tcp" template="json-template" TCP_Framing="delimited" Delimiter="\n")
这个配置会让RSyslog每条JSON日志结尾加上换行符,Logstash就能正确识别单条JSON消息了。
2. 确认RSyslog的TCP模块已加载
检查/etc/rsyslog.conf顶部是否有加载相关模块的配置,如果没有,加上:
module(load="imtcp") # 加载TCP输入模块(若需接收TCP syslog) module(load="omfwd") # 确保转发模块已加载(默认可能已加载,但确认更稳妥)
3. 验证Logstash输入配置匹配
确保你的Logstash TCP输入配置使用json codec,因为RSyslog已经把日志转成JSON格式了:
input { tcp { port => 10514 codec => json } }
如果之前你用的是syslog codec,那肯定会解析失败——毕竟RSyslog输出的是JSON,不是原始syslog格式。
测试与验证
- 重启RSyslog服务:
sudo systemctl restart rsyslog
- 发送一条测试日志:
logger -t myapp "TCP JSON test message"
- 查看Logstash的日志或索引,确认是否能正确解析出
@timestamp、message、sysloghost等所有字段。
额外排查点
如果上面的方法还是不行,可以试试:
- 用
tcpdump抓包查看TCP传输的内容:sudo tcpdump -i lo port 10514 -A,检查是否是完整的JSON字符串,每条是否以换行结尾。 - 升级RSyslog到最新稳定版本,旧版本的TCP输出可能存在格式兼容问题。
内容的提问来源于stack exchange,提问作者Akhilesh Joshi
相关产品推荐
相关产品推荐

