4. Syslog 服务器搭建(rsyslog)

说实话,日志收集这件事,很多人觉得简单——不就是装个 rsyslog,改两行配置吗?我一开始也这么想。直到有一次线上故障排查,发现日志丢了一堆,才意识到搭建一个靠谱的 syslog 服务器,里面的门道比想象中多。

这一章,我们就从头捋一遍 rsyslog 的搭建过程。我会带你避开那些坑,把配置做到生产可用的级别。

4.1 为什么选 rsyslog?

你可能会问:Linux 自带的 syslogd 不好吗?我用过,功能太弱了。rsyslog 的优势很明显:

  • 性能高:支持多线程,单机每秒能处理百万级日志。
  • 模块化:输入、输出、解析都可以插拔。
  • 协议全:UDP、TCP、RELP、TLS 都支持。
  • 过滤强:基于属性、正则、时间范围等灵活路由。
我的习惯:新项目一律用 rsyslog,老旧系统迁移也优先考虑它。社区活跃,文档齐全,遇到问题好查。

4.2 安装与基础配置

安装很简单。CentOS/RHEL 上:

yum install rsyslog -y

Ubuntu/Debian:

apt-get install rsyslog -y

装完后检查版本:

rsyslogd -v

我个人习惯用 v8 以上,因为支持 omelasticsearch 等高级输出模块。

默认配置在 /etc/rsyslog.conf。先看看整体结构:

# 模块加载
module(load="imuxsock")   # 本地系统日志
module(load="imklog")     # 内核日志

# 全局设置
$WorkDirectory /var/lib/rsyslog
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

# 规则:按设施和级别路由
*.info;mail.none;authpriv.none;cron.none   /var/log/messages
authpriv.*                                  /var/log/secure
mail.*                                      /var/log/maillog
cron.*                                      /var/log/cron
*.emerg                                     :omusrmsg:*
注意:生产环境不要直接改默认配置。我建议拆分文件,方便维护。在 /etc/rsyslog.d/ 下创建自定义文件,比如 50-default.conf。

4.3 核心架构:模块化处理流水线

rsyslog 的架构可以理解为一条处理流水线:输入 → 预处理 → 过滤器 → 输出。理解这个对排错很有帮助。我画了一张图,帮你直观理解:

rsyslog 日志处理流水线 输入模块 imuxsock / imtcp 预处理 解析 / 正则替换 过滤器 if / property 输出模块 omfile / omfwd 可路由到多个目标 文件 / 远程 / ES / 队列 整个处理链都在内存队列中执行,支持背压和重试 配置指令对应每个阶段的参数

这个流水线设计,让 rsyslog 能灵活应对各种场景。比如,你可以在预处理阶段去掉敏感 IP,在过滤器里只保留 ERROR 级别日志,最后分别输出到本地文件和远程服务器。

4.4 实战:搭建远程日志接收服务器

最常见的需求是把所有服务器的日志集中到一个地方。我们来配一个接收端(server)。

在 /etc/rsyslog.conf 中启用 TCP/UDP 接收:

# 加载 TCP 和 UDP 模块
module(load="imtcp")
module(load="imudp")

# 监听端口
input(type="imudp" port="514")
input(type="imtcp" port="514")

然后按来源主机存放日志:

# 模板
$template RemoteLogs,"/var/log/remote/%FROMHOST-IP%/%$YEAR%-%$MONTH%-%$DAY%.log"

# 规则:远程日志全走这个模板
*.* ?RemoteLogs
& ~
关键点:& ~ 表示停止处理当前消息,防止重复写入本地日志。如果不加,远程日志会同时写入 /var/log/messages,磁盘很快被打满。

重启服务:

systemctl restart rsyslog

检查端口是否监听:

ss -tuln | grep 514

4.5 客户端配置

客户端只需要把日志转发出去。在 /etc/rsyslog.conf 中加入:

*.* @@192.168.1.100:514   # 双@表示TCP,单@表示UDP

更严谨的做法是用 RELP 协议,保障可靠传输。不过那是进阶内容,我这里先不展开。

4.6 日志轮转:别让磁盘爆炸

远程日志量很大,不轮转的话,一周就能撑满硬盘。我的做法是用 logrotate:

/var/log/remote/*/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}
我曾经踩过的坑:忘了 kill -HUP 重启 rsyslog,导致日志文件被删除后进程仍然持有文件句柄,磁盘空间不释放。所以 postrotate 那步不能省。

4.7 性能调优三板斧

当每秒日志量超过 1 万条时,默认配置会顶不住。我一般调这三个参数:

参数 默认值 推荐值 说明
$MainMsgQueueSize 10000 50000 主队列容量,防突增
$ActionQueueSize 1000 10000 每个输出动作的队列
$ActionQueueMaxDiskSpace 1G 5G 队列溢出时落盘空间

配置示例:

global(
    defaultNetstreamDrv="gtls"
    defaultNetstreamDrvKeyFile="/etc/rsyslog-key.pem"
    main_queue(
        queue.size="50000"
        queue.dequeueBatchSize="200"
        queue.timeoutShutdown="60000"
    )
)

4.8 安全加固

远程接收日志,默认没有鉴权。至少要做两件事:

  • 防火墙限制来源 IP:只允许内网网段访问 514 端口。
  • 使用 TLS 加密:防止日志在传输中被篡改或嗅探。

TLS 配置大致如下(证书准备略):

# 服务端
module(load="imtcp" StreamDriver.AuthMode="x509/name"
                StreamDriver.Mode="1"
                StreamDriver.Name="gtls")
input(type="imtcp" port="6514")

# 客户端
*.* @@(o)logserver.example.com:6514
我的建议:刚开始可以先用 UDP 测试,稳定后再切 TCP+TLS。一步到位容易给自己埋坑。

4.9 常见问题与避坑指南

  • 日志不写入:先检查 selinux 和 apparmor,再查看 /var/log/messages 中 rsyslog 自身的报错。
  • 时间戳不对:客户端没有启用 systemd-timesyncd,导致日志时间漂移。我曾遇到过跨时区问题,排查了一下午。
  • 队列满了丢日志:调大 $MainMsgQueueSize 并监控磁盘 I/O。
  • 端口被占用:有些系统自带的 syslogd 占用了 514,先停掉它。

rsyslog 搭建本身不难,难的是应对生产环境的复杂流量。记住几个核心点:模块化配置、队列调优、安全加固、日志轮转。搭建完成后,记得压测一下。用 logger 命令模拟发送大量日志,观察 CPU 和磁盘负载,确认没问题再正式上线。