首页 / 资讯中心 / 文章详情

rsyslog集中式日志服务器:从规划到排障实战

rsyslog集中式日志服务器:从规划到排障实战 ★ FEATURED ARTICLE
1. 为什么需要集中式日志单机排查的痛点与集中式架构的收益生产环境里最常见的一个场景几十台甚至上百台 CentOS 主机同时跑着业务有 Web 服务、有数据库、有任务调度、有应用程序自己写的业务日志。平时不出问题的时候一切正常一旦某个节点出了故障你就会陷入一场灾难——登录一台又一台机器反复敲tail -f、grep、less翻遍/var/log/messages、secure、cron和各个应用的自定义日志目录凭感觉和运气定位问题。运气好半小时找到线索运气不好可能一个下午都耗在这上面。我自己经历过一次印象很深的排障某天凌晨有台机器磁盘告警但日志太多等我把那台机器里相关的片段拼凑起来业务已经中断两个小时了。事后我想如果当时所有主机的日志都汇聚到一个地方用一条命令就能按时间范围、按主机名、按关键字去检索那这个问题可能十分钟就能定位。这就是搭建集中式 Syslog 服务器最直接的价值让日志不再散落在各台机器的文件里而是统一收集、统一存储、统一检索。从技术选型角度看集中式 Syslog 并不是什么新概念但它依然是目前运维体系里性价比极高的基础设施。你不需要引入一个重型的日志平台不需要庞大的对象存储和复杂的检索集群——仅仅是一台带够磁盘的 CentOS 主机配合系统自带的rsyslog守护进程就能把全网的日志稳定地收过来。CentOS 从 7 开始默认就装好了 rsyslog这个服务本身就是一个功能很完整的 Syslog 收集端支持 UDP、TCP 甚至 RELP 多种传输方式能配置模板、过滤规则、远程转发完全能满足中小规模集群的日志归集需求。这篇文章适合谁看我认为有三类人第一类是刚接手运维、需要给手上的一批 Linux 主机做一个日志归集方案的基层运维第二类是系统架构师要在一套新环境里快速搭出日志采集层为后续对接分析平台做准备第三类是那些已经在用但只是照着文档配完就跑的人——如果你想知道每个配置项背后的原理、哪些参数会影响可靠性、出问题该从哪里排查这篇文章也能给你一个比较完整的参考。我下面讲的内容是基于我在真实环境里的配置方法和踩坑经验整理的不保证是最官方的姿势但一定是我验证过能稳定运行的方案。先从规划说起。2. 配置前的核心决策传输协议、存储规划与基础环境2.1 选 TCP 还是 UDP可靠性优先还是兼容性优先Syslog 协议本身是 UDP 设计的514 端口发出去就不管了。但生产环境的日志收集可靠性是一个绕不开的问题。日志一旦在网络传输过程中丢失事后排查问题时你根本不知道是没产生日志还是丢了日志这会直接误导排查方向。如果你面前的场景是几台机器、网络稳定、日志量不大UDP 的确省心客户端配置简单服务端也不用维护连接状态性能开销小。但一旦主机数超过几十台或者网络偶尔有抖动我强烈建议使用 TCP。TCP 有确认机制客户端发送的数据会确认到达服务端才会从缓冲区移除丢日志的概率远低于 UDP。代价是服务端需要为每个客户端维护一个连接连接数上来后占用的句柄和内存会多一些但对一台 2C4G 的日志服务器来说几百个连接完全不是问题。还有一个更稳妥的选择是 RELPReliable Event Logging Protocol它是 rsyslog 项目专门设计的可靠传输协议既有应用层确认又支持队列持久化。但当客户端数量多、涉及的机器系统版本杂的时候RELP 的兼容性是个额外的负担。我的建议是通用场景首选 TCP关键业务节点再单独配置 RELP没必要一开始就在所有机器上强制统一。2.2 磁盘规划日志服务器最容易踩的资源坑集中式日志服务器有一个天然矛盾日志只在出问题时才有价值但它每时每刻都在增长。我见过不少团队服务器配置的时候没想清楚跑三个月磁盘就满了然后迫不得已写个脚本定期删日志——结果真的出问题时需要的日志正好被删了。磁盘规划的核心原则很简单按留存天数和日均日志量反推容量预留。比如你有 50 台客户端每台每天产生 200MB 系统日志实际很多机器根本到不了这个量一天就是 10GB。如果你要保留 30 天那至少需要 300GB 可用空间。建议再留出 20%-30% 的余量给日志轮转的间隙和其他临时文件。存储介质上SATA 机械盘足够顺序写日志对 IOPS 要求不高但一定要把日志目录放在独立分区或者独立磁盘上不要和系统盘共用。否则日志一涨直接把系统盘塞满连登录都困难。我自己的习惯是日志服务器单独挂一块数据盘挂载到/var/log/remote目录下rsyslog 的所有远程日志都写到这里彻底和系统自身的日志隔离。这样即使远程日志把空间耗尽系统盘上的基础日志和业务应用还能正常运转。2.3 基础环境准备系统版本、时间同步与防火墙预留CentOS 7 和 CentOS 8/9 的 rsyslog 配置有细微差别但核心参数基本一致。我这篇以 CentOS 7 的 rsyslog 8.24 版本为主CentOS 8/9 的差异点我会在文末单列出来。在动手配置之前有几项基础检查必须提前做掉不然后面排查难度翻倍时间同步集中式日志里时间戳是排序和关联的命脉。客户端和服务端都必须配置 NTP 时间同步否则同一时刻的日志在不同主机上的时间可能差出几秒甚至几分钟检索时根本对不齐。主机名规范每台客户端最好都设置规范的主机名因为 rsyslog 默认会在收到的日志里带上发送方的主机名。如果主机名不统一后期按主机过滤日志的时候会非常痛苦。防火墙预留端口默认端口 514 需要被放行。注意 TCP 和 UDP 都要放行因为后面你可能会从 UDP 切换到 TCP或者同时收两种协议的日志。# 服务端放行示例以 firewalld 为例 firewall-cmd --permanent --add-port514/udp firewall-cmd --permanent --add-port514/tcp firewall-cmd --reload上面这些做完基础就算打好了。接下来进入最核心的环节服务端 rsyslog 配置。3. rsyslog 服务端配置主配置文件改写与关键参数解析3.1 拆解主配置文件模块加载、全局指令与规则段CentOS 上 rsyslog 的主配置文件在/etc/rsyslog.conf。打开这个文件你看到的是三个部分模块加载部分、全局指令部分、规则部分。模块加载部分最常见的是imuxsock负责接收本地系统日志和imjournalCentOS 7 上从 journald 导入日志。集中式服务端必须要新增的是imtcp和imudp两个模块分别对应 TCP 和 UDP 的远程日志接收。# 在 rsyslog.conf 的 modules 段添加 module(loadimuxsock SysSock.Useoff) # 关闭本地 socket避免占用默认路径 module(loadimjournal StateFile/var/lib/rsyslog/imjournal.state) module(loadimudp) input(typeimudp port514) module(loadimtcp) input(typeimtcp port514)这里我特别说明一下SysSock.Useoff这个参数。默认情况下 rsyslog 会监听本地系统的/dev/log套接字把本机所有用户的日志都收进来。如果你只是做一个远程日志收集器这台机器本身不跑业务那监听本地 socket 并没有太大意义而且有可能造成日志重复或者权限问题。关掉它让这台服务器专注处理网络日志是一个更干净的配置方式。imjournal模块建议保留因为 CentOS 7 上很多系统组件只往 journald 里写日志保留它你还能在本机看到自己这台服务器的原始日志。全局指令部分要设置的几个关键项$WorkDirectory /var/lib/rsyslog # rsyslog 工作目录存放队列文件和状态文件 $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat $ActionQueueType LinkedList # 使用内存队列 $ActionQueueFileName remote_fwd # 队列文件名前缀 $ActionResumeRetryCount -1 # 失败后无限重试 $ActionQueueSaveOnShutdown on # 关闭时保存队列数据注意$ActionQueueType LinkedList和$ActionQueueFileName组合这是设备端向远端转发时使用队列的关键配置。如果你只用这台机器做接收-写盘队列配置主要影响的是接收后写盘的可靠性。但如果这台服务器还要把日志再转发给上一级那队列配置就是性命攸关的——它决定了当上级服务器不可用时日志是在本地排队还是直接丢弃。3.2 目录结构设计按主机名和日期分文件存储所有人收进来的日志都堆在一个文件里是最糟糕的设计检索时复杂度直线上升。我的做法是收到日志后按主机名和日期拆分成不同的文件存储。这样单台机器单天的日志就是一个文件按天归档非常清晰。这需要用到 rsyslog 的模板功能。模板定义了日志写入文件的路径和格式。下面这个模板是我的标准配置$template RemoteLogs,/var/log/remote/%hostname%/%$YEAR%-%$MONTH%-%$DAY%.log这个模板的关键在于%hostname%变量。rsyslog 收到日志时会优先使用 syslog 协议头里的 hostname 字段作为主机名来源。如果客户端配置正确那么每台机器收上来的日志会自动归类到以它主机名命名的目录里。日期部分用%$YEAR%、%$MONTH%、%$DAY%这些系统变量按自然日拆分文件后续做日志轮转也方便。引用模板的规则段写法如下# 把所有远程日志按上述模板写入 *.* ?RemoteLogs stop这里?RemoteLogs的语法表示使用名为 RemoteLogs 的模板来生成目标文件路径。 stop的意思是当日志匹配这条规则并写入文件后不再继续传递给后续规则避免重复处理。这个规则要放在配置文件的最后面同时要在将它置于与该机器上其他规则不同的优先级下我们通常把它放在*.info等默认规则之前或之后取决于你是否还希望这些远程日志也被写到本地 messages 里。实际配置里我通常直接在文件里注释掉原来的本地日志规则只保留远程接收和写入让这台服务器成为一个纯粹日志接收器。3.3 模板格式与时间戳精度为什么我推荐高精度格式rsyslog 默认的传统格式RSYSLOG_TraditionalFileFormat时间戳精度只有秒。在高并发系统里同一秒内发生的日志事件顺序可能和实际执行顺序不一致这会导致按时间排序时出现错误。所以我在模板里额外指定了高精度时间戳格式。$template RemoteFormat,%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg%\n这个格式输出的时间戳带毫秒和时区信息例如2024-01-15T14:23:45.12345608:00。配合前面的目录模板写文件的规则就变成*.* ?RemoteLogs;RemoteFormat分号后面指定的是内容格式模板分号前面的是文件路径模板。这个写法在 rsyslog 里很常见建议在配置之前先小范围测试一下确认文件路径和内容格式都符合预期再大规模铺开。3.4 验证服务端配置的正确性配置文件检查与重启改完配置文件后一定要先做语法检查。rsyslog 有一个专门用于检查配置的命令rsyslogd -N 1这个命令会解析配置文件并输出错误信息-N 1表示只做检查、不实际启动。如果输出里有error字样要逐条修正后再试。一切正常的话重启服务systemctl restart rsyslog systemctl status rsyslog然后验证端口是否在监听ss -lntup | grep 514如果你发现 514 端口没有监听第一反应不用去改配置先确认是不是 SELinux 在拦截这个问题我后面的排障章节会重点展开。端口正常监听之后就可以从任意一台客户端发一条测试日志过来了。你可以在服务端用tcpdump或者直接去看日志目录有没有生成对应文件来验证。4. 客户端日志转发配置从单机到集中式的切换4.1 客户端最小配置一个 rsyslog.d 文件搞定客户端配置比服务端简单很多。CentOS 的 rsyslog 支持把配置放在/etc/rsyslog.d/目录下主配置文件末尾有include语句会自动加载这个目录。我建议不要改主配置文件的规则而是新建一个独立文件例如/etc/rsyslog.d/60-remote.conf专门负责远程转发。这样升级系统或者重新安装时主配置文件的默认规则还在不会互相干扰。# /etc/rsyslog.d/60-remote.conf *.* 192.0.2.10:514这里表示使用 TCP 协议发送单个是 UDP。192.0.2.10是日志服务器地址你要替换成实际的服务器 IP。端口默认 514。就这么简单一条规则就能把本机所有 syslog 协议的日志包括用户进程通过 logger 写入的、内核通过 klog 写入的、各种服务通过网络 syslog 写入的全部转发到远端。4.2 只转发部分日志用级别和设施过滤但所有日志全转发有时候不是最优解。举个例子本机的messages文件里每秒会产生大量调试信息或周期性任务日志如果这些都堆到集中式服务器上存储压力会增大。你完全可以按需选择。# 只转发 info 级别以上且排除 cron 和 local7 *.info;cron.none;local7.none 192.0.2.10:514这个规则的含义所有设施facility的 info 及以上级别日志都转发但cron设施和local7设施除外。local7通常被一些服务当作自定义日志通道使用如果你不想把这些也收上来可以在这里排除掉。你还可以用local0、local1等自定义设施来区分不同服务的日志。很多应用程序支持通过 syslog 发送日志并且可以指定 facility。比如你可以在应用里把业务日志配置为local0然后在 rsyslog 客户端配置里单独把local0转发到另一台服务器或不同的端口。# 业务日志单独转发到 515 端口 local0.* 192.0.2.10:515这样一来一台日志服务器可以监听多个端口把系统日志和业务日志从物理上分开存储后续做数据隔离和权限控制都方便一些。4.3 系统日志与 journald 的关系避免重复转发CentOS 7 一个容易踩的坑是 systemd-journald 和 rsyslog 同时存在。很多服务例如 sshd、crond的日志会先进入 journald再由 rsyslog 从 journald 里读取后转入传统 syslog 流程。这种情况下你配置的转发规则收到的是从 journald 转出来的日志一般不会重复。但有一种情况会产生重复如果某些程序直接同时向 journald 和 syslog 写日志少数程序有这个行为或者你在 rsyslog 配置里同时开启了imuxsock和imjournal且规则里都匹配了同一类日志就可能出现同一条日志被转发两次的情况。排查重复日志的时候先检查这两点不要在客户端业务层面找原因。4.4 客户端连通性测试一条命令验证转发链路配置完客户端之后不要直接等日志自己过来。建议立即用logger命令手动制造一条测试日志logger -n 192.0.2.10 -P 514 test message from client但注意这条命令是直接向远端发送 syslog 报文绕过了本机 rsyslog 的转发配置。如果你想测试 rsyslog 的转发规则是否生效应该用logger test message from rsyslog forwarding这个命令会通过imuxsock或者/dev/log进入本机 rsyslog然后由你配置的规则转发出去。在服务端查看收没收到用tail -f /var/log/remote/客户端主机名/今天日期.log看到测试消息说明链路通了。如果没看到按我后面第 6 章的排查链路去查。5. 日志轮转、安全加固与存储增长控制5.1 日志轮转配置避免单个文件无限膨胀写进logrotate的配置策略直接影响存储和检索体验。远程日志目录下的文件如果无限增长单个文件膨胀到几个 GB 之后任何grep操作都会变慢甚至磁盘占满导致 rsyslog 停止接收。所以一定要配置 logrotate。新建/etc/logrotate.d/rsyslog-remote文件内容如下/var/log/remote/*/*.log { daily rotate 30 compress delaycompress missingok notifempty create 0640 root root sharedscripts postrotate /bin/kill -HUP cat /var/run/rsyslogd.pid 2/dev/null 2/dev/null || true endscript }解释几个关键参数daily按天轮转和之前模板里按日期分文件的策略配合含义是同一个目录下的文件如果在同一天不断增长到点就切分。rotate 30保留 30 个轮转后的旧文件也就是大约 30 天的历史数据。compress轮转后压缩成.gz能大幅节省磁盘。delaycompress延迟压缩即轮转后最新的一个文件不立即压缩。因为 rsyslog 可能还在往旧文件句柄里写数据立即压缩可能导致数据丢失。create 0640 root root轮转后新文件的权限和属主。postrotate通知 rsyslog 重新打开日志文件。如果不做这一步rsyslog 会一直往已经被轮转掉的文件句柄里写磁盘空间释放不出来。一个常见的问题是我用模板按%hostname%和日期生成了文件为什么同一天里文件还会变大因为模板里的%$DAY%只精确到天如果你配置里写的是%$YEAR%-%$MONTH%-%$DAY%那同一天的日志都会追加到同一个文件这个文件的体积会持续增长。这就是为什么 logrotate 的daily策略和模板的按日分文件要结合使用——模板负责逻辑上的数字日期标识logrotate 负责物理上的切分和压缩两者配合才是完整的生命周期管理。5.2 防火墙与监听范围限制不要把 514 裸奔到公网日志内容非常敏感里面可能包含登录记录、应用配置、网络请求信息等。如果把 514 端口直接暴露到公网且没有任何访问限制等于把你整个集群的内部运行情况拱手送人。至少要做以下安全加固只监听内网网卡不要监听所有网卡。如果服务器有多个网卡rsyslog 的input可以指定绑定地址。在防火墙层面限制来源 IP只允许信任的网段访问。考虑使用单独的日志传输网段把日志流量与业务流量隔离。# 限制来源网段示例 firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.0.2.0/24 port port514 protocoltcp accept firewall-cmd --permanent --add-rich-rulerule familyipv4 source address192.0.2.0/24 port port514 protocoludp accept firewall-cmd --reload对于安全要求更高的环境rsyslog 还支持 TLS 加密传输通过gtls驱动加载证书配置会复杂一些。如果你的日志需要跨公网传输或者有合规审计要求TLS 是值得投入的。但如果是纯内网环境且网络本身可信防火墙配合内网隔离已经能覆盖大部分风险。5.3 存储告警在磁盘爆炸前介入日志服务器的一个常见故障模式是磁盘慢慢被日志占满然后 rsyslog 无法写文件开始静默丢日志直到有人发现问题。为了防止这种情况我建议在日志服务器上配置磁盘使用率告警。最简单的方案是用cron配合一条命令检查磁盘空间# /etc/cron.d/disk-check */10 * * * * root /usr/local/bin/check-disk.shcheck-disk.sh 脚本内容#!/bin/bash threshold85 current$(df -h /var/log/remote | awk NR2 {print $5} | tr -d %) if [ $current -gt $threshold ]; then echo 日志服务器磁盘使用率已达 ${current}% | mail -s Log Server Disk Warning opsexample.com fi不过邮件在紧急的时候未必能被及时看到更稳妥的做法是接入你已有的监控体系无论是 Zabbix、Prometheus 告警还是简单的钉钉/企微机器人 webhook。监控项不用多磁盘使用率、514 端口的连通性、最近 5 分钟是否有新日志写入这三个指标够了。5.4 日志的远程转发把日志服务器再接到上一级如果你的架构是多机房或者多级汇总日志服务器收上来的数据还要继续往上一级传比如传到一个集中的审计平台。rsyslog 规则支持在同一台机器上先收再转。# 在服务端配置中追加 *.* 10.0.0.10:514这里要特别注意如果你原配置里有 stop规则转发的规则必须写在stop之前否则日志在被写入本地文件后就被丢弃永远不会进入转发流程。我用过多个生产环境这个问题出现的频率极高十次有八次是因为规则顺序的问题导致上级平台收不到日志。6. 实战排障端口不通、日志丢失与时间错乱的排查链路6.1 514 端口不监听的真相SELinux 才是第一嫌疑很多人在配置完 rsyslog 后发现端口没有监听第一反应是检查配置文件、检查服务状态但都正常。这时候 90% 的可能是 SELinux 拦截了 rsyslog 对非标准端口的监听或对特定目录的写入。CentOS 7 默认开启了 SELinux而 rsyslog 相关的 SELinux 布尔值里允许监听 514 默认是被开启的但允许 rsyslog 使用非标准端口的行为可能需要额外开启。如果你是改到 5514 这样的非默认端口或者修改了日志写入目录SELinux 策略没跟上服务会启动失败但systemctl status rsyslog未必能看到特别明显的报错更多时候只是端口没起来服务显示 active。快速验证是不是 SELinux 问题的方法# 临时禁用 SELinux 保护再测试 setenforce 0 systemctl restart rsyslog ss -lntup | grep 514如果停掉 SELinux 之后端口正常监听说明问题确实在 SELinux 策略上。不要图省事长期关闭 SELinux正确做法是调整布尔值让 rsyslog 能使用需要的能力# 允许 rsyslog 监听相关端口和访问网络 setsebool -P rsyslogd_support_syslog 1如果你的日志目录在/var/log/remote这类非默认路径还需要修改该目录的 SELinux 类型semanage fcontext -a -t var_log_t /var/log/remote(/.*)? restorecon -Rv /var/log/remote这里var_log_t是日志文件的标准类型。如果不做这一步rsyslog 即使端口监听正常往这个目录写文件时也会被 SELinux 拒绝文件可能创建成功但写入失败。这类问题非常隐蔽只会在运行一段时间后你发现日志目录里没有文件而客户端明明在正常转发。6.2 客户端有日志但服务器收不到从抓包到规则排查客户端确认配置了转发服务端也确认没有收到日志这种情况我梳理了一套排查顺序你按照这个来基本上 15 分钟内能定位在客户端确认日志确实进入了 rsyslog。执行logger测试消息后查看本机转发队列有没有报错。在客户端抓包看报文是否真的发出去了tcpdump -i eth0 host 192.0.2.10 and port 514如果没有报文问题在客户端 rsyslog 规则没匹配或者服务没生效如果有报文问题在服务端。在服务端抓包tcpdump -i eth0 port 514服务端如果没有收到报文检查中间防火墙、路由器 ACL如果收到了报文但日志文件里没有那问题一定在服务端的规则匹配或文件写入权限。在服务端查看 rsyslog 内部的状态启用调试日志可以这样说rsyslogd -di输出会非常多但能直观看到每条消息经过哪些规则、匹配到了什么模板、最终写到哪里。这个链路里最容易出问题的环节是客户端 rsyslog 里的规则没有把所有日志都纳入转发。比如默认配置里如果有一条*.info;mail.none;authpriv.none;cron.none的规则后面又加了一条*.* server看起来没问题但如果你加规则的顺序不对或者在这条前面已经有一条 stop日志就可能被提前截住。规则顺序在 rsyslog 里非常敏感务必确认stop在最后。6.3 时间错乱集中式日志的头号排序杀手日志服务器收到不同客户端的日志时时间字段来自客户端发送的 syslog 包头。如果客户端和服务端之间有时间差哪怕只有几秒从多个来源检索日志时就会看到类似客户端 A 的 14:00:01 日志排在客户端 B 的 14:00:03 日志之后这种乱序现象。排查时先在服务端执行chronyc sources -v确认服务端本身时间源是同步状态。然后在每台客户端执行chronyc tracking看System time这一项偏差值超过 1 秒就要处理。常见的导致偏差的原因客户端 NTP 服务没启动或者只同步了一次就不再同步。防火墙挡了 NTP 的 123 端口少见但发生过。虚拟化环境里宿主机时间漂移导致客户机时间同步不稳定。如果日志已经收上来了排查时发现时间错乱你可以用%timereported%在服务端重新打时间戳。具体做法是在服务端模板里把%TIMESTAMP%换成%timereported:::date-rfc3339%这样文件里记录的时间就是服务端接收时刻的时间而不是客户端发送时写的时间。这样做的好处是日志在服务端的时间维度是完全一致的坏处是原始客户端时间信息会在一定程度上被覆盖。我的建议是尽量搞时间同步服务端模板保持显示客户端时间只有在实在无法同步的极端情况下才考虑用接收时间替代。6.4 重复日志消息重复与多路径接收的排查当你发现同一条日志出现两次时先不要急着改配置。可能的三层原因客户端既写了 journald 又让 rsyslog 转发并且服务端的imjournal和imudp/imtcp同时接收到了同一条消息。这种情况在 CentOS 7 上不算罕见因为它本身就有两条日志链路。客户端配置了多条匹配规则例如一条*.* server和一条authpriv.* server后一条可能覆盖了前一条的一部分导致部分日志被重复发送。服务端配置了多个 input 模块指向同一个端口或者配置文件被重复加载。排查的最直接办法是在服务端对同一时间段内收到的日志做去重统计。比如用awk统计某个文件里相同内容的行数awk {print $0} /var/log/remote/hostA/2024-01-15.log | sort | uniq -c | sort -rn | head发现大量2出现就说明有重复。然后回到客户端用rsyslogd -N 1检查配置规则是否有重叠或者直接临时停掉imjournal相关配置来隔离问题。7. 向后兼容与多协议接入CentOS 8/9 差异与老设备适配7.1 CentOS 8/9 的配置区别新版 rsyslog 的语法差异CentOS 8/9 默认的 rsyslog 版本是 8.2102 以上较老版本有了不少变化。主要差异点在于新版 rsyslog 对input(typeimtcp)这类 RainerScript 语法支持更完整配置文件风格更统一。$ActionQueue系列指令在新版本中也能使用但官方更推荐在新的queue()参数中配置。默认的 systemd unit 文件路径和 PID 文件位置有变化/var/run/rsyslogd.pid在新版里的读取位置可能变成/run/rsyslogd.pid。logrotate 的 postrotate 脚本里要注意兼容。如果你在 CentOS 8/9 上遇到了语法检查报错常见的情况是某些$开头的传统指令和模块加载指令混用导致冲突。我的建议是统一使用新版语法类似global(workDirectory/var/lib/rsyslog) module(loadimtcp MaxSessions500) input(typeimtcp port514 rulesetremote)使用ruleset可以把远程日志和本地日志的处理规则完全分离避免相互干扰。这是个很好的实践尤其是 CentOS 8/9 默认可能同时配置了 journald 转储和传统 syslog 规则用ruleset能显著降低规则冲突概率。7.2 同时接收 TCP 与 UDP老网络设备的兼容方案网络设备交换机、路由器、防火墙大多只支持 UDP 方式的 syslog 发送有些老设备对 syslog 协议的支持也比较原始。如果你的网络里有这类设备不要强迫它们升级到 TCP 或 RELP一个折中方案是服务端同时监听 UDP 和 TCPmodule(loadimudp) input(typeimudp port514) module(loadimtcp) input(typeimtcp port514)要注意的是UDP 日志没有连接概念来源 IP 可以伪造而且老设备的日志内容格式通常比较野很多用本地时间而不是标准 RFC3339 格式。如果你的服务端模板强制要求某种时间格式可能导致解析异常。我的做法是针对老设备单独设置一个端口比如 UDP 5514和一套更宽松的模板专门接收它们的日志不和 Linux 客户端的日志混在一起。这样既兼容了老设备又不会影响 Linux 日志的格式统一。7.3 从旧版日志服务器迁移保留历史日志还是重新开始如果你是替换一台旧的日志服务器或者从其他开源方案比如 syslog-ng迁移过来要考虑历史日志是否保留。rsyslog 本身没有历史数据的导入工具最简单的方法是直接把旧日志文件拷贝到新服务器的对应目录然后通过配置相同的主机名规则继续写入。但要注意旧日志的文件命名规则如果和新模板不一致就无法自动合并。我的建议是如果历史日志量不大直接把旧文件归档到新服务器的历史目录不参与实时写入。如果历史日志量很大且需要长期审计建议在新服务器上设置一套独立的归档目录用 rsyslog 的file模块或者定时任务把旧文件压缩存储不要和实时日志混用否则检索时会非常混乱。迁移过程中最容易忽略的是旧服务器上有没有其他应用直接往日志目录里写入自定义文件或者有没有 cron 任务依赖这些路径。迁移前先梳理清楚所有依赖以免新服务器上线后某些脚本失效。8. 实测中的意外情况与长期维护建议8.1 常见配置错误速查表我把自己和团队踩过的坑整理成了一张速查表方便你对照检查症状大概率原因快速验证解决方式514 端口未监听SELinux 拦截setenforce 0后测试调整布尔值或文件上下文日志文件目录无文件目录权限或 SELinux 类型不正确ls -lZ检查上下文restorecon修复客户端有日志但服务端空白防火墙拦截或规则顺序错误tcpdump双向抓包检查防火墙和 rsyslog 规则顺序日志重复出现journald 与 rsyslog 双链路统计同内容行数调整规则去重时间顺序错乱NTP 未同步或时钟漂移chronyc tracking修正时间同步磁盘快速占满未配置 logrotate 或模板粒度太粗du -sh /var/log/remote/*配置轮转和压缩这张表在你自己搭建过程中如果遇到问题可以先对照看看。很多时候问题不是单一的而是多个原因叠加导致的所以排查的时候要按链路一步步来不要跳过任何一步。8.2 长期维护日志服务器自身健康度如何看部署完成只是工作的三分之一后面还有长期的运维观察。日志服务器本身要看的指标包括连接数使用 TCP 接收时连接数等于在线客户端数。如果连接数远小于实际客户端数说明有客户端断连了网络不通或 rsyslog 服务停止。写延迟磁盘 IO 达到瓶颈时rsyslog 的队列会积压表现为客户端日志到达时间明显滞后。队列文件增长/var/lib/rsyslog下的队列文件如果异常增大说明上一级转发目标不可达日志积压在本地队列中。# 查看当前 rsyslog 进程的打开文件和队列大小 lsof -p $(pidof rsyslogd) | grep -E queue|imjournal du -sh /var/lib/rsyslog/*每天或者每周做一次简单的巡检比等出问题再人工翻日志要省事得多。我记得有一次是某个星期队列文件涨到了 2GB而转发目标机器早就停机维护了——如果当时没有巡检等目标机器恢复后一次性补传 2GB 数据那对磁盘 IO 和网络带宽都是不小的冲击。8.3 一点实操体会测试与灰度最好这样做最后分享一个我自己的习惯建议你在任何大范围部署前先走一遍先准备一台测试机作为客户端把配置按最终方案写好然后观察至少 24 小时。不要只看日志有没有收到要重点观察三点一是文件目录结构是否符合预期二是时间戳是否准确三是每天产生的日志量是否符合估算。确认这三项没问题再批量推广到所有机器。批量部署时如果你管理的主机比较多建议用配置管理工具推送 rsyslog 配置而不是手动逐台去改。配置推送后要立即检查每台机器的 rsyslog 服务状态避免出现配置错误导致服务起不来的情况。回滚方案也要准备好一旦有机器转发异常能快速恢复到纯本地日志模式。另外建议给每台客户端打上带 IP 和业务用途的备注例如在主机名里包含业务信息。这样后续日志检索时看到主机名就能大概知道是哪套系统排查效率会高很多。我在生产环境里见过不少主机名叫localhost或者只有 IP 的机器收上来的日志根本分不清来源非常影响使用体验。9. 最后再给一个小技巧用本地测试设施验证配置如果你改完配置不确定规则对不对又不想发测试消息污染生产日志有一个很实用的技巧在客户端临时使用local6设施发一条测试日志然后在服务端配置一条单独的规则把它输出到一个临时文件。验证后再把这条规则删掉。# 客户端发送 logger -p local6.info validation test# 服务端临时规则 local6.* /var/log/remote/test-validation.log这样测试完不会混入正式的按主机名归档的文件也方便清理。等确认链路无误后把临时规则从服务端配置里移除再在客户端正常使用logger或者让业务日志自然流入。集中式 Syslog 服务器这套方案我已经在两三个规模的集群里跑过稳定性和实用性都经住了考验。它不复杂但每一步都有值得注意的细节。希望这篇从规划到配置、再到排障和长期维护的完整梳理能帮你省下那些我当初摸索时浪费的时间。如果你在实际配置中遇到了这篇文章之外的新坑欢迎带着现场情况来交流——排除故障的过程往往比最终方案本身更有价值。
阅读完成 · 觉得有帮助?
咨询建站