Syslog 模块的故障自检方法及常见已知问题
Rsyslog 版本:8.24.0
1. 故障自检方法
1.1. 无日志输出
现象:
目标进程的预期日志文件无日志写入, tail -f
未检测到日志写入流
1 | sudo tail -f /var/log/syslog |
1.1.1. 可能原因 1:目标进程未启动或异常
自检方法:排查目标进程运行状态,或结合进程自身特性判断
1 | 检查业务进程是否正常运行(eg. swss 容器中的 fdbmgrd 进程 ) |
1.1.2. 可能原因 2:Rsyslog 未启动
可能原因 2-1:
系统日志软件 Rsyslog 进程被 Kill
自检方法:检查 Rsyslog 是否运行
1 | 1. 检查交换机中 Rsyslog 是否运行 |
可能原因 2-2:
Rsyslog 的自身配置文件 /etc/rsyslog.conf
或自定义配置文件夹下 /etc/rsyslog.d/
的配置有错,导致 Rsyslog 启动失败
自检方法:对照正常设备的配置
1.1.3. 可能原因 3:无程序打开目标日志文件
自检方法:查看是否有进程打开目标日志文件(eg. /var/log/syslog
)
1 | 检查有无进程“打开了”目标日志文件 |
一般情况如下:
1 | COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME |
1.1.4. 可能原因 4: 日志输出限制级别设定过高
自检方法:通过 swssloglevel 或 logctl 命令检查日志输出限制级别是否过高
1 | 查看当前日志输出限制级别 |
应对方法:
- 更改输出限制级别
1 | 降低目标进程(eg. fdbmgrd)日志输出限制级别 |
备注:查看更改日志输出限制级别用法
1 | swssloglevel -h |
1.2. 日志文件无法轮转,无限制增长
现象:
日志文件无限制增长,超过轮转阈值,却未被轮转压缩
1.2.1. 可能原因 1:logrotate 配置异常
自检方法:排查 logrotate 配置
1 | 1. 检查有无安装 logrotate |
1.2.2. 可能原因 2:cron 配置异常
logrotate 日志轮转依赖于被定时任务工具 cron 周期调起
自检方法:排查 cron 配置
1 | 1. 检查 cron 配置(对照正常设备配置) |
1.3. 轮转后新文件不记日志
现象:
日志文件大小为 0,已自检不是“1.1. 无输出日志”的问题
1.3.1. 可能原因:Rsyslog 未收到 HUP 信号
日志轮转工具 logrotate 在轮转
xxx.log
文件后,理应给 Rsyslog 发 HUP 挂起信号,以使 Rsyslog 进程能够重新加载 新的xxx.log
文件的(文件 inode 号变更)进行记日志。
Rsyslog 未收到 HUP 信号,其仍根据旧 inode 向不存在的前 xxx.log
写日志。
自检方法:检查该日志文件对应的 lorotate 轮转配置文件(eg. /etc/logrotate.d/rsyslog
),确保 postrotate 执行块内,存在向 Rsyslog 发送 HUP 信号的操作
1 | postrotate |
2. 常见已知问题
2.1. 高速刷日志时突然停止输出
现象:
短时输出大量日志时突然无征兆中断输出,5 分钟后日志又恢复输出,循环往复,导致日志呈现周期性断续输出现象
根因:
日志吞吐量过高时,会触发容器中 Rsyslog 配置的“熔断”值(2 万条/每 5 分钟),此时容器中 Rsyslog 会停止转发日志消息到宿主机 Rsyslog,故宿主机端观检测不到日志输出。不过,进入下一 5 分钟周期计数清零后,日志又恢复输出。
注意:“熔断”期间的输出日志会丢失。
自检方法:查看目标容器(eg. bgp)中的 Rsyslog 配置文件 /etc/rsyslog.conf
1 | docker exec -it bgp grep -C 2 "SystemLogRateLimitInterval" /etc/rsyslog.conf |
默认配置如下:
1 | Set a rate limit on messages from the container |
应对方法:
- 更参考1.1.4改日志输出的级别,以降低日志输出速率
- 临时调高 Rsyslog 配置的“熔断”值
1 | 修改目标容器(eg. bgp)中 Rsyslog 的“熔断”配置值 |
2.2. Rsyslog 收到 HUP 信号
现象:
Rsyslog 收到 HUP 信号并输出下方的 INFO 级别日志。
1 | 2021-10-16 03:50:01.212971 HOSTNAMR <local7.info> INFO liblogging-stdlog: [origin software="rsyslogd" swVersion="8.24.0" x-pid="1732" x-info="http://www.rsyslog.com"] rsyslogd was HUPed |
根因:
符合预期的正常情况。当日志文件发生轮转时,Rsyslog 会收到 logrotate 发送的 HUP 信号,重新加载文件,包括停止往已改名的“准轮转文件”写日志,而是写日志到新建的一个同名文件中。
2.3. Rsyslog 折叠重复日志
现象:
Rsyslog 输出下方的折叠日志
1 | 2021-10-27 15:57:44.222512 HOSTNAMR <local2.err> ERR swss#orchagent: message repeated 1636 times: [ :- doTask: op: SET, key: vlan23:8.1.1.2] |
根因:
出现 message repeated 1636 times
,是由于容器中的 Rsyslog 开启了“减少重复日志” 开关(默认开启),以避免一千多行重复冗余日志转发的性能消耗,是符合预期的正常情况。
自检方法:查看目标容器(eg. bgp)中的 Rsyslog 配置文件 /etc/rsyslog.conf
1 | docker exec -it bgp grep -B 2 "RepeatedMsgReduction" /etc/rsyslog.conf |
默认配置如下:
1 | Suppress duplicate messages and report "message repeated n times" |
2.4. Rsyslog 打印 2354 标识
现象:
Rsyslog 输出下方日志
1 | 2021-09-26 11:20:58.668466 HOSTNAMR <local7.err> ERR liblogging-stdlog: omfwd: error 11 sending via udp: Resource temporarily unavailable [v8.24.0 try http://www.rsyslog.com/e/2354 ] |
Rsyslog 打2354 标识日志表明很可能是系统的 UDP 缓冲区空间不足。
(注:旧版本(如 8.24)也无法发送接近或大于 64KiB 的日志消息)
根因:
系统的 UDP 缓冲区空间不足。还需监控系统的 UDP 缓存区占用情况来定位是哪些组件占用较大(可参考:监控 UDP buffer 可用空间)
2.5. Rsyslog 打印 2359 标识
现象:
Rsyslog 输出下方日志
1 | 2021-09-26 10:35:02.802106 HOSTNAMR <local7.info> INFO liblogging-stdlog: action 'action 0' resumed (module 'builtin:omfwd') [v8.24.0 try http://www.rsyslog.com/e/2359 ] |
根因:
Rsyslog 恢复服务的提示日志,2359 标识 表示 之前由于重连到服务器或资源不再紧缺时暂停的操作现已恢复执行,符合预期无需处理。
2.6. Rsyslog 打印 2007 标识
现象:
Rsyslog 输出下方日志
1 | 2022-05-06 15:30:34.575869 HOSTNAMR <local7.warning> WARNING liblogging-stdlog: action 'action 0' suspended, next retry is Fri May 6 15:31:04 2022 [v8.24.0 try http://www.rsyslog.com/e/2007 ] |
根因:
2007 标识的常见原因为 Rsyslog 配置中包含向不可达组件写日志的错误配置,如配置了不可达的远程日志服务器,将导致输出大量2007标识的告警信息。
解决方法:
删除/注释错误的远程日志服务器配置后重启rsyslog服务。
2.7. 无 Redis 自身运行日志
现象:
未记录 Database 中 Redis 的相关运行日志
根因:
Database 容器里的 redis 配置中,默认未配置日志输出
自检方法:查看 Redis 配置文件 /etc/redis/redis.conf
1 | docker exec -it database grep -B 2 "syslog-enable" /etc/redis/redis.conf |
默认配置如下:
1 | To enable logging to the system logger, just set 'syslog-enabled' to yes, |
应对方法:
- 修改 Redis 配置文件,添加日志输出配置,并重启 Redis 以生效(不建议线上设备执行此操作)
1 | 1. 备份原配置 |
- redis-cli 虽然也支持热修改部分日志配置,但不支持热修改开启/关闭日志输出
1 | 1. 热修改 Redis 输出日志路径配置 |
2.8. 修改 Rsyslog 配置文件后未生效?
修改 Rsyslog 配置文件后,需要重启服务以生效配置
1 | sudo service rsyslog restart |
2.9. 一条日志能够重定向到多个日志文件么?
可以,在 Rsyslog 配置中(/etc/rsyslog.d/00-HOSTNAMR.conf
),若 syslog 消息匹配了多条自定义重定向(引流)规则(且规则执行块内无结束匹配关键字 stop),就能实现输出单条日志到多个文件
多条自定义重定向(引流)单日志到多个文件如下:
- 在配置文件
/etc/rsyslog.d/00-HOSTNAMR.conf
中添加两条自定义重定向(引流)规则
1 | # test rule1 |
- 模拟发送一个 syslog 消息
1 | logger -p local5.info "ABC DEF TEST1" |
- 可发现两个重定向(引流)日志文件都记录了该日志
1 | 2021-12-29 15:14:18.698602 HOSTNAMR <local.info> INFO admin: ABC DEF TEST1 |
2.10. Rsyslog 支持修改日志的 facility 么?
问题补充描述:程序打 local0 的日志,能否让 Rsyslog 在写日志文件时改为 local2 ?
暂不支持,截止官网 8.2112.0 版本,Rsyslog 暂不支持修改日志 facility 的操作;网上也没有成功修改案例。
虽然 Rsyslog 支持的“读已有日志文件并按行转发”功能中支持指定日志 facility,理论上存在“引流 local0 日志 ==> 指定文件 ==> 读文件转成 syslog 消息(指定 local2)”这种可能,但这种方式不具备可行性:
- 首先是这种“二次转发”的日志会存在冗余消息前缀,如
1 | 原始日志 |
- 其次,这种打日志后再读文件二次转发方式,由于写入文件与读文件二次转发逻辑问题,一条日志很容易陷入被无限打印循环
2.11. 获知程序对应的日志路径?
由于 Rsyslog 主要基于程序打日志的 facility、或少量自定义的重定向(引流)规则明确记日志的文件 /etc/rsyslog.d/00-HOSTNAMR.conf
,故暂无进程与日志文件的明确对应关系。不过依然可以参考下方两种方式获知进程的日志文件路径:
- 方法 1:查看梳理的各容器启停日志及各进程输出日志
- 方法 2:手动检索
/var/log/
目录(检索字段:容器名#进程名)
1 | sudo grep -Rw "swss#fdbmgrd" /var/log/ | awk '{ print $1 }' | uniq | sort | uniq |
2.12. 日志服务器未收到上报日志?
咱们的日志上报是CS架构,下方任一原因都可能导致日志服务器无法收到日志:
设备端:
- Rsyslog 服务未运行?检查命令:
1 | sudo systemctl status rsyslog | grep Active |
- 设备上是否配置 远程日志服务器IP 检查命令:
1 | grep -A 2 'remote syslog server' /etc/rsyslog.conf |
- 日志服务器不可达?检查命令:
1 | ping $(grep -A 1 'remote syslog server' /etc/rsyslog.conf | tail -n +2) |
- 防火墙 配置?514 端口未打开?检查命令:
1 | sudo iptables -L -n |
- 设备无异常日志输出? 检查命令:
1 | sudo grep -E 'NOTICE|WARNING|ERROR' /var/log/syslog | grep local2 | tail -20 |
日志服务器端:
- Rsyslog 服务未运行?检查命令:
1 | sudo systemctl status rsyslog | grep Active |
- 防火墙 配置?514 端口未打开?检查命令:
1 | sudo iptables -L -n |
- Rsyslog 配置中 $UDPServerAddress 127.0.0.1 被打开了?服务器端需注释,否则只能接收本地日志检查命令:
1 | grep 'UDPServerAddress' /etc/rsyslog.conf |
- 服务器端配置了日志全转发? 检查命令:
1 | grep -A 2 'remote syslog server' /etc/rsyslog.conf |