用 rsyslog + logrotate 即可稳定实现日志集中管理,无需 elk 或自研脚本;关键在于客户端启用 tcp 传输与磁盘队列、服务端按源 ip 分目录存储、logrotate 针对子目录单独轮转,并验证队列、接收与归档三环节。

直接用 rsyslog + logrotate 组合就能稳定实现,不需要额外部署 ELK 或自写脚本。关键不是“传过去”,而是“传得稳、存得住、不丢、可追溯”。
rsyslog 客户端必须用 TCP 并启用磁盘队列
UDP 传日志看似简单,但丢包无声无息——比如网络抖动、目标机短暂不可达,rsyslog 默认就直接丢弃。改用 TCP 是底线,再加磁盘缓冲才能扛住短时故障。
- 编辑客户端
/etc/rsyslog.conf或/etc/rsyslog.d/10-remote.conf - 添加这三行(替换
192.168.1.100为目标服务器 IP):module(load="omfwd")<br>action(type="omfwd" protocol="tcp" target="192.168.1.100" port="514" queue.filename="rsyslog_queue" queue.maxdiskspace="1g" queue.saveonshutdown="on" queue.type="disk")
-
queue.filename必须唯一,避免多个 action 冲突;queue.maxdiskspace建议设为 500M–1G,太小容易满,太大占空间 - 重启服务:
sudo systemctl restart rsyslog
rsyslog 服务端要按源 IP 分目录存储
如果所有客户端日志都混写进同一个 /var/log/syslog,归档时根本分不清哪条来自哪台机器,排查和权限隔离都成问题。按 IP 自动分目录是刚需。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 在服务端
/etc/rsyslog.d/20-remote.conf中配置模板和规则:$template RemoteLogs,"/var/log/remote/%FROMHOST-IP%/%$YEAR%-%$MONTH%-%$DAY%.log"<br>*.* ?RemoteLogs<br>& stop
-
%FROMHOST-IP%是真实来源 IP,不是转发中间设备的 IP;若经 NAT,需在客户端配置$PreserveFQDN on并用%hostname% - 确保
/var/log/remote/目录存在且rsyslog用户有写入权限:sudo mkdir -p /var/log/remote && sudo chown syslog:adm /var/log/remote - 重启服务:
sudo systemctl restart rsyslog
logrotate 要为每个远程主机目录单独配规则
不能只轮转 /var/log/syslog,而要轮转 /var/log/remote/192.168.1.101/*.log 这类路径。否则旧日志堆积在子目录里,logrotate 根本看不见。
- 新建
/etc/logrotate.d/remote-logs,内容示例:/var/log/remote/*/[^.]*.log {<br> daily<br> rotate 30<br> compress<br> delaycompress<br> missingok<br> notifempty<br> create 0640 syslog adm<br> sharedscripts<br> postrotate<br> systemctl kill --signal=HUP rsyslog 2>/dev/null || true<br> endscript<br>} -
[^.]*.log排除.log.1、.log.gz等已归档文件,防止重复处理 -
postrotate发 HUP 是为了让rsyslog关闭旧文件句柄(虽然它通常自己会 reopen,但显式通知更稳妥) - 测试是否识别到文件:
sudo logrotate -d /etc/logrotate.d/remote-logs | grep rotating
验证归档是否真正生效的三个硬指标
别只看 cron 是否跑了,要盯住三个地方:磁盘队列有没有积压、远程目录有没有新文件生成、压缩后文件名是否带日期。任何一项异常,归档链就断了。
- 查客户端磁盘队列状态:
sudo rsyslogd -N1(看输出里是否有queue.filename="rsyslog_queue"),再查文件是否存在:ls -lh /var/spool/rsyslog/rsyslog_queue* - 查服务端是否收到日志:
sudo tail -n1 /var/log/remote/192.168.1.101/$(date +%Y-%m-%d).log,确认时间戳和内容合理 - 手动触发一次归档并观察:
sudo logrotate -f /etc/logrotate.d/remote-logs,然后检查/var/log/remote/192.168.1.101/下是否出现2026-09-07.log.gz类文件
最常被忽略的是服务端磁盘空间和权限:/var/log/remote/ 目录如果被 root 占满或 chmod 错误,rsyslog 会静默失败,日志全丢,连错误都不记——因为它自己就是记日志的程序。










