到了生产环境,日志同步就别再用UDP了,原因很直接:一旦丢包,往往还是静默丢失,排查起来非常被动。更稳妥的做法是使用TCP。对应到rsyslog配置上,imtcp模块需要显式加载,并通过input监听514端口;客户端写转发规则时,必须使用@@,不能写成@。另外,队列配置、SELinux布尔值以及基于%FROMHOST-IP%的模板,也都得一并配好,这几项少了任何一个,整套方案都很难真正跑稳。

生产环境必须用 TCP 协议同步日志,UDP 会静默丢包,排查时根本不知道日志没传过去。
服务端监听 514 端口要显式启用 imtcp 模块
要先明确一点:rsyslog 默认并不会去监听任何网络端口,所以只改配置思路是不够的,实际上不会生效。必须在 /etc/rsyslog.conf 或 /etc/rsyslog.d/ 目录下的任意配置文件中,先把对应模块加载进来,再把输入源明确声明好。
- 取消注释或追加
module(load="imtcp") - 紧接着写
input(type="imtcp" port="514")(别漏掉括号和引号) - 若只配了模块但没写
input行,ss -tnl | grep 514看不到监听,systemctl restart rsyslog也不会报错——这是最常被忽略的一步 - UDP 同理:需
module(load="imudp")+input(type="imudp" port="514"),但生产环境不推荐
客户端转发规则必须用 @@ 而不是 @
@ 是 UDP,@@ 才是 TCP。很多故障源于抄错一个字符:
- 错误写法:
*.* @192.168.1.100:514→ 日志发出去就消失,服务端收不到,tcpdump -nn port 514抓不到包 - 正确写法:
*.* @@192.168.1.100:514;RSYSLOG_ForwardFormat→ 分号后加格式模板,避免时间戳/主机名丢失 - 必须配队列参数,否则网络抖动时日志直接丢:
$ActionQueueFileName fwdRule1、$ActionQueueMaxDiskSpace 1g、$ActionQueueSa veOnShutdown on - SELinux 启用时,需运行
setsebool -P rsyslog_forward on,否则连接会被静默拒绝
日志按 IP 分类存储必须用 %FROMHOST-IP% 模板
用 %HOSTNAME% 不可靠——主机名可能被伪造、重复或解析失败;%FROMHOST-IP% 才是真实来源:
- 定义模板:
$template RemoteLogs,"/var/log/remote/%FROMHOST-IP%/%PROGRAMNAME%.log" - 应用规则:
*.* ?RemoteLogs(注意问号,不是分号) - 目录需提前创建并赋权:
mkdir -p /var/log/remote/192.168.1.5+chown syslog:adm /var/log/remote/192.168.1.5 - 若模板路径含非法字符(如冒号、斜杠),rsyslog 会静默跳过写入,
journalctl -u rsyslog -f里会出现invalid template提示
真正难的不是写对几行配置,而是验证每层都通:客户端能连上 514 端口(nc -vz 192.168.1.100 514)、服务端 ss 看到监听、tcpdump 抓到包、目录权限正确、模板变量不为空——缺一环,日志就卡在半路。