Rsyslog 集中化日志实战:搭建高可靠日志服务器
用 Rsyslog 搭建集中化日志服务器完整教程——客户端 UDP/TCP/TLS/RELP 转发、服务端按主机分文件落盘、磁盘辅助队列的缓冲与丢失边界、与 logrotate 配合轮转。并讲解更近一步的做法:让 Rsyslog 直接转发给观测云 DataKit,省掉自建日志存储的运维负担。
集中化日志(Centralized Logging)是指把多台机器的日志通过网络汇聚到一台(或一组)日志服务器统一存储和检索的架构——它解决三个问题:机器故障后日志仍可查、跨机器关联分析不用挨个登录、安全审计有独立副本。Rsyslog 是实现它的经典工具,本篇给出从零搭建的完整配置,并讨论何时该把"集中化的终点"从自建服务器换成观测云这样的托管平台。
核心要点速览
- 最小可用架构:服务端
imudp/imtcp接收 + 模板按主机名分文件;客户端*.* @server:514(UDP)或@@(TCP)转发。 - 生产环境至少上 TCP,丢不得的日志上 RELP 或 TLS+磁盘队列;UDP 只适合内网、可容忍少量丢失的场景。
- 集中化的终点不一定是文件:让 Rsyslog 把日志转发给 DataKit 的 syslog 输入,直接进入观测云,检索、告警、留存策略全部托管。
如何搭建 Rsyslog 日志服务器(接收端)?
/etc/rsyslog.d/10-server.conf:
module(load="imtcp")
module(load="imudp")
template(name="RemoteHostFile" type="string"
string="/var/log/remote/%hostname:::secpath-replace%/%programname:::secpath-replace%.log")
ruleset(name="remote") {
action(type="omfile" dynaFile="RemoteHostFile"
createDirs="on" dirCreateMode="0750" fileCreateMode="0640")
stop
}
input(type="imtcp" port="514" ruleset="remote")
# 仅在发送端需要时启用 UDP
input(type="imudp" port="514" ruleset="remote")
先确认运行用户可创建目录/文件及SELinux策略,防火墙仅允许授权发送网段,再校验配置并重启:
sudo mkdir -p /var/log/remote
sudo rsyslogd -N1
# 按授权来源网段配置514/tcp或udp入站规则,勿无差别向公网开放
sudo systemctl restart rsyslog
客户端如何转发?
/etc/rsyslog.d/90-forward.conf:
# UDP(一个 @)
*.* @192.168.1.10:514
# 或 TCP(两个 @)
*.* @@192.168.1.10:514
只想转发部分日志,用选择器过滤:auth,authpriv.* @@192.168.1.10:514(只转认证日志)。
UDP、TCP、RELP 怎么选?
| 协议 | 可靠性 | 说明 |
|---|---|---|
| UDP | 可能丢包 | 开销最小;内网、日志量大且少量丢失可接受时用 |
| TCP | 可靠字节流,不保证端到端日志无损 | 通用推荐;注意服务端连接数 |
| RELP | 应用层确认,仍需队列/持久化设计,可能重复 | Rsyslog 生态专用协议,需要两端都装 rsyslog-relp;关键日志首选 |
RELP 配置(端口 2514 是惯例):服务端 module(load="imrelp") + input(type="imrelp" port="2514");客户端 module(load="omrelp") + *.* :omrelp:192.168.1.10:2514。
网络中断时如何不丢日志?
给转发动作挂磁盘辅助队列(客户端侧):
global(workDirectory="/var/spool/rsyslog")
action(
type="omfwd"
target="192.168.1.10"
port="514"
protocol="tcp"
template="RSYSLOG_ForwardFormat"
action.resumeRetryCount="-1"
queue.type="LinkedList"
queue.filename="central-forward"
queue.maxDiskSpace="1g"
queue.saveOnShutdown="on"
)
服务器宕机期间,LinkedList队列通常先在内存,溢出才辅助落盘;saveOnShutdown只保护受控退出,强杀/掉电可能丢内存。磁盘容量有限,恢复后吞吐还需高于新增流量才能追平——这是集中化架构可靠性的关键一环。
传输安全怎么做?
跨机房或跨公网必须上 TLS:用 gtls 网络流驱动(rsyslog-gnutls 包),服务端证书 + 客户端验证 StreamDriverAuthMode="x509/name",防止日志被窃听或伪造。防火墙白名单限制来源但不能替代TLS的加密与认证;TLS也不等于持久化或exactly-once交付。
集中日志的轮转与清理
/etc/logrotate.d/remote-logs:
/var/log/remote/*/*.log {
daily
rotate 14
compress
delaycompress
sharedscripts
missingok
notifempty
postrotate
/bin/kill -HUP `cat /var/run/rsyslogd.pid 2>/dev/null` 2>/dev/null || true
endscript
}
rotate 14控制轮转文件数量,不保证精确14个日历日。postrotate 发 HUP 让 rsyslog 重新打开文件句柄,否则它会继续写已轮转的 inode。
需要在集中存储之外检索多台主机的日志时,也可以保留 Rsyslog 汇集,再转发给观测云 DataKit。转发前先确认接收端协议、监听端口和日志解析规则:
- Rsyslog → DataKit:在 DataKit 所在主机开启 syslog 采集(TCP/UDP 及端口按实际配置),Rsyslog 客户端直接转发给 DataKit:
或者在现有集中服务器上用 Rsyslog 再跳转发给 DataKit,先用单台主机验证转发,避免重复采集;集中接收ruleset内转发需放在stop之前。*.* @@datakit-host:9540 # 仅在DataKit按当前logging socket示例监听此端口时使用 - 统一打标与解析:DataKit 采集配置中标注
service;用 Pipeline 把 syslog 头部解析出time和status,让不同设施的日志在观测云里字段对齐。 - 检索与告警:日志查看器按实际解析的
host、service过滤;无日志检测需结合正常上报频率设置窗口,并区分主机没有新日志与转发链路中断。 - 成本:按查询频率和保留期配置索引,需要长期归档时另行配置数据转发;上线前验证目标存储中的样本能否读取。
常见问题(FAQ)
Q:服务器收到的日志时间戳乱怎么办? 客户端时钟不同步是主因,所有节点配 NTP/chrony;另外注意 syslog 传统格式不带年份,Rsyslog 模板建议用 RSYSLOG_ForwardFormat(含年份和高精度时间)。
Q:一万台客户端 UDP 打过来服务端扛得住吗? UDP 高并发下内核缓冲区易溢出丢包,调大 net.core.rmem_max 并给 imudp 配 rcvbufSize;更稳妥是分流到 TCP/RELP 或多台接收器 + 负载均衡。
Q:集中化日志需要保留多久? 看合规:等保、金融审计通常 6 个月起。用 logrotate 管理热数据,超期需求交给观测云归档索引或对象存储生命周期。
Q:容器环境还适合 Rsyslog 集中化吗? 容器主机的 /var/log/messages、syslog 依然可以用这套方案;容器自身的 stdout 日志建议直接用 DataKit 的容器日志采集(《Docker 日志驱动》),不必绕经宿主机 syslog。
系列阅读
[1]: 观测云文档《Syslog》https://docs.guance.com/integrations/syslog/
[2]: 观测云文档《DataKit 日志采集综述》https://docs.guance.com/integrations/datakit-logging/
[3]: 观测云文档《日志查看器》https://docs.guance.com/logs/explorer/
[4]: 观测云文档《日志-索引》https://docs.guance.com/logs/multi-index/