rsyslog上传长日志至Graylog被截断,netcat却正常的原因排查
这个问题我之前排查过类似场景,核心差异就在于两者对UDP大消息的处理逻辑完全不同,尤其是默认的大小限制设置:
1. netcat的处理逻辑
netcat发送大消息时,会自动把内容拆分成符合UDP MTU(以太网环境下一般是1472字节,也就是1500字节的网络MTU减去IP头20字节+UDP头8字节)的数据包逐个发送。而Graylog的UDP输入接收器默认支持UDP分片重组,会把这些零散的数据包重新拼接成完整的原始消息,所以最终能看到完整内容。
2. rsyslog的默认限制坑
rsyslog通过UDP发送日志时,默认受$ActionSendUDPMaxMessageSize参数(新版rsyslog是udp.maxMessageSize选项)限制,这个参数的默认值通常是8192字节(不同版本可能有差异,老版本甚至可能是1024字节)。当日志消息超过这个阈值时,rsyslog不会像netcat那样拆分数据包,而是直接截断超出的部分,这就导致Graylog收到的消息缺了尾巴。
另外要注意,rsyslog的输入端也有$MaxMessageSize参数,但你这里是往Graylog发消息,所以重点是发送端的配置。
怎么解决rsyslog的截断问题?
你需要修改/etc/rsyslog.conf(或者对应的子配置文件,比如/etc/rsyslog.d/graylog.conf),调整UDP发送的最大消息大小:
方式一:传统rsyslog配置格式
在配置Graylog的UDP发送动作之前,添加这行配置:
$ActionSendUDPMaxMessageSize 65507
65507是UDP数据包的理论最大容量(65535字节的UDP总长度减去IP头和UDP头的28字节),设置这个值后,rsyslog会尽可能发送完整消息,超过MTU的部分会自动拆分数据包(较新版本的rsyslog都支持这个功能)。
然后确保你的Graylog发送动作配置正确,比如:
*.* @1.2.3.4:1514;RSYSLOG_SyslogProtocol23Format
方式二:新版rsyslog的rainerscript语法
如果你的rsyslog用的是现代的rainerscript格式,配置要写成这样:
module(load="omudp") action( type="omudp" target="1.2.3.4" port="1514" template="RSYSLOG_SyslogProtocol23Format" udp.maxMessageSize="65507" )
最后验证
修改完配置后重启rsyslog服务:
systemctl restart rsyslog
再发送长消息测试,应该就不会被截断了——rsyslog会把大消息拆成多个UDP包发送,Graylog会自动重组这些分片,完整显示消息内容。
额外提醒
- 确保Graylog的UDP输入配置没有设置过小的消息大小限制,Graylog默认是65535字节,一般不用调整。
- 如果你的网络环境MTU较小(比如低于1500字节),可以适当降低
udp.maxMessageSize的值,避免数据包在网络层被分片丢失,但大部分以太网环境1500字节MTU是没问题的。
内容的提问来源于stack exchange,提问作者Paul

