在企业环境中,将多台服务器的系统日志集中到一台 Rsyslog 服务器上,便于统一管理和故障排查。但日志文件会不断增长,必须为不同客户端实现日志分离存储和自动轮转。本文将一步步带你完成从安装、配置到调试的全过程,并教你如何修改日志存储位置。
1. 环境准备
- 日志服务器:Ubuntu 22.04 / CentOS 7+ (本文以 Ubuntu 为例)
- 客户端:任意支持 syslog 的设备
- 网络:服务器开放 UDP/TCP 514 端口
2. 安装 Rsyslog
大多数 Linux 发行版默认已安装 rsyslog。若未安装:
# Ubuntu/Debian
sudo apt update && sudo apt install rsyslog -y
# CentOS/RHEL
sudo yum install rsyslog -y查看版本并确认服务状态:
rsyslogd -v
sudo systemctl status rsyslog3. 配置服务器接收远程日志
编辑 /etc/rsyslog.conf 或新建 /etc/rsyslog.d/remote.conf。
3.1 加载网络模块并监听端口
# 接收 UDP 日志(常用)
module(load="imudp")
input(type="imudp" port="514")
# 如需 TCP(更可靠)
module(load="imtcp")
input(type="imtcp" port="514")3.2 为不同客户端创建独立日志文件
使用 模板(template) 动态生成文件名,例如按客户端主机名存放:
# 定义模板:将日志写入 /var/log/remote/客户端主机名.log
template(name="PerHostLog" type="string" string="/var/log/remote/%HOSTNAME%.log")
# 将所有接收到的日志应用该模板
*.* ?PerHostLog注意:%HOSTNAME%是客户端发送的主机名(也可能是 IP)。如果想用 IP,可使用%FROMHOST-IP%。
3.3 可选:丢弃本地日志,仅作为专用日志服务器
如果服务器自身日志不需要写入上述远程路径,可以单独保留系统日志规则。但通常我们会让本地日志走原有规则,远程日志走新规则,互不干扰。
完整配置示例(/etc/rsyslog.d/remote.conf):
# 接收 UDP 日志
module(load="imudp")
input(type="imudp" port="514")
# 动态文件模板
template(name="PerHostLog" type="string" string="/var/log/remote/%HOSTNAME%.log")
# 写入远程日志
*.* ?PerHostLog
# 禁止将远程日志再写入本地 messages 等文件(可选)
& stop& stop 表示匹配到的日志不再继续往下传递。
4. 创建日志存储目录并重启服务
sudo mkdir -p /var/log/remote
sudo chown syslog:adm /var/log/remote # Ubuntu 下 rsyslog 通常以 syslog 用户运行
sudo systemctl restart rsyslog验证监听端口:
sudo netstat -tuln | grep 5145. 客户端配置
在任意客户端上,编辑 /etc/rsyslog.conf 或 /etc/rsyslog.d/99-remote.conf,添加:
# 发送所有日志到日志服务器(UDP)
*.* @192.168.1.100:514
# 若使用 TCP(一个 @ 是 UDP,两个 @@ 是 TCP)
# *.* @@192.168.1.100:514重启客户端 rsyslog:
sudo systemctl restart rsyslog6. 调试与验证
6.1 检查日志是否到达服务器
在服务器上实时监控某个客户端的日志文件:
sudo tail -f /var/log/remote/client-hostname.log在客户端使用 logger 发送测试消息:
logger "Test message from client"6.2 常见问题排查
| 问题 | 检查方法 | |
|---|---|---|
| 端口未监听 | `ss -tuln \ | grep 514` |
| 防火墙阻挡 | sudo ufw allow 514/udp 或 iptables -L | |
| 文件未生成 | 检查 /var/log/remote 权限,以及模板语法是否正确 | |
| 主机名显示为 IP | 在客户端配置中设置 $PreserveFQDN on,或模板改用 %FROMHOST-IP% |
7. 配置 logrotate 自动轮转日志
现在每个客户端的日志文件都在 /var/log/remote/*.log。我们需要为这些文件设置轮转策略,避免磁盘占满。
创建 /etc/logrotate.d/rsyslog-remote:
/var/log/remote/*.log {
daily
rotate 30
compress
missingok
notifempty
dateext
create 0640 root root
sharedscripts
postrotate
/usr/bin/systemctl kill -s HUP rsyslog.service
endscript
}参数说明:
daily:每天轮转一次(也可用size 100M按大小轮转)rotate 30:保留 30 个归档文件dateext:轮转后文件名追加当前日期,例如 access.log-20260411.gzcompress/delaycompress:压缩旧文件,但当前轮转的那个不立即压缩create:轮转后新建文件,指定权限和属主sharedscripts:所有文件轮转完后只执行一次postrotate脚本postrotate:向 rsyslog 发送 HUP 信号,让其重新打开日志文件(必须!)
手动测试轮转配置:
sudo logrotate -vf /etc/logrotate.d/rsyslog-remote执行后检查 /var/log/remote/ 目录,应出现 .log.1 或 .gz 文件。
8. 更改日志存储位置
如果默认的 /var/log/remote/ 空间不足,需要迁移到其他磁盘(例如 /data/logs/remote/)。
8.1 修改 rsyslog 模板
编辑 /etc/rsyslog.d/remote.conf,更改模板中的路径:
template(name="PerHostLog" type="string" string="/data/logs/remote/%HOSTNAME%.log")8.2 创建新目录并设置权限
sudo mkdir -p /data/logs/remote
sudo chown syslog:adm /data/logs/remote8.3 修改 logrotate 配置
更新 /etc/logrotate.d/rsyslog-remote 中的路径:
/data/logs/remote/*.log {
# 其余参数不变
}8.4 重启服务并迁移旧日志(可选)
sudo systemctl restart rsyslog
# 若需迁移旧日志
sudo mv /var/log/remote/* /data/logs/remote/9. 进阶技巧
9.1 按日期生成子目录
如果需要每天自动创建子目录,可以使用更复杂的模板:
template(name="DailyPerHostLog" type="string" string="/data/logs/remote/%$YEAR%/%$MONTH%/%$DAY%/%HOSTNAME%.log")但要注意:logrotate 无法直接轮转这种深层目录下的文件,需要配合 cron 脚本或使用 rsyslog 自带的 outchannel 功能。一般不建议过度复杂化,简单单文件轮转已足够。
9.2 使用 rsyslog 自带轮转(替代 logrotate)
rsyslog 可以基于文件大小轮转,例如在模板后添加:
*.* action(type="omfile" file="/var/log/remote/%HOSTNAME%.log" fileSizeLimit="100M" action.execOnlyWhenPreviousIsSuspended="on" ioBufferSize="64kb")但 logrotate 更灵活,推荐继续使用。
10. 总结
通过以上步骤,你已经完成了一个生产可用的远程日志服务器:
- ✅ 接收多客户端日志并按主机名分离存储
- ✅ 使用 logrotate 自动压缩、轮转、清理旧日志
- ✅ 能够任意更改日志存储位置
- ✅ 掌握调试与故障排查方法
这套方案可以轻松扩展到数百台客户端,并配合监控工具(如 ELK、Loki)实现日志分析。如果在配置中遇到问题,欢迎留言交流。