rsyslog启动卡在“activating (start)”状态时,需用-n2检查逻辑死锁(如模板未定义、条件无限嵌套),结合strace观察系统调用阻塞点,并逐段注释rainerscript配置隔离问题。

rsyslog 配置中缺少分号或存在隐蔽语法死锁(如模板循环引用、条件规则无限嵌套、未闭合的括号/引号块)时,服务常表现为启动卡在“activating (start)”状态,长时间无响应,不是崩溃也不是报错,而是静默挂起。这类问题不触发 -N1 语法检查失败,却让 rsyslog 主进程无法完成初始化,必须从加载行为和执行路径切入排查。
用 -N2 检查逻辑完整性,暴露隐性死锁
基础语法检查(-N1)只验证语句结构,对模板定义是否被正确引用、if 条件块是否形成闭环、$template 是否存在未解析变量等逻辑陷阱无能为力。-N2 会模拟规则加载过程,强制解析所有模板和条件分支:
- 运行 rsyslogd -N2 -f /etc/rsyslog.conf,重点观察输出末尾是否有 "template 'xxx' not found"、"undefined variable" 或 "infinite loop detected in ruleset" 类提示
- 若使用 include,需对每个被包含文件单独执行 -N2:例如 rsyslogd -N2 -f /etc/rsyslog.d/99-custom.conf
- 常见死锁诱因:在 if 语句中调用另一个未定义的 template;使用 $!myvar 但未通过 mmjsonparse 解析 JSON;RainerScript 中写成 if $msg contains "error" then { action(type="omfile" file="/var/log/error.log") } 却遗漏了 else 分支,导致后续规则无法进入
观察进程行为,确认是否卡在模块加载阶段
挂起通常发生在模块初始化或规则编译环节。直接查看 rsyslog 进程实际在做什么:
使用ydata-profiling(前身为pandas-profiling)生成全面的数据质量报告,包含相关性分析、缺失值模式和基数检测。导出交互式HTML仪表板和JSON摘要。
- 启动前先清空日志缓冲:journalctl --rotate && journalctl --vacuum-size=50M
- 执行 systemctl start rsyslog 后立即运行:ps auxf | grep rsyslog —— 若看到进程状态为 S(sleep)且 CPU 占用持续为 0%,说明正阻塞在某个系统调用上(如等待 socket、读取配置文件某一行)
- 用 strace -p $(pgrep rsyslog) -e trace=open,openat,read,futex 捕获系统调用流,重点关注是否反复 open 同一配置文件、或卡在 read() 调用上(暗示某处语法未终结,解析器持续等待更多输入)
临时禁用高风险语法组件,逐段隔离
分号缺失和死锁多集中在新式 RainerScript 区域(尤其是 if/else、call、ruleset 定义)。安全做法是注释掉全部非必要逻辑块,只保留最简骨架:
- 备份原配置后,在 /etc/rsyslog.conf 开头添加:# module(load="imuxsock")\n# module(load="imklog")\n# *.* /var/log/messages
- 然后逐步取消注释:先放开 module 加载,再加一条基础规则,再加一个 template,最后加 if 块 —— 每加一行就 systemctl restart rsyslog 测试一次
- 特别注意引号嵌套:例如 template(name="jsonout" type="list") { property(name="$!all-json") } 中若 $!all-json 未被解析,整个 template 将无法实例化,导致后续所有依赖它的 action 挂起
检查 systemd 启动超时与依赖链干扰
某些发行版(如 Ubuntu 22.04+)默认设置 DefaultTimeoutStartSec=90s,而 rsyslog 在死锁时可能耗尽该时限,被 systemd 强制 kill 并重试,造成“反复启动失败”假象:
- 运行 systemctl show rsyslog.service | grep TimeoutStartSec 确认实际超时值
- 查看完整启动轨迹:systemctl status rsyslog --no-pager,留意 “Activating…” 后是否出现 “timed out” 或 “Killed” 字样
- 检查是否存在循环依赖:例如 rsyslog 配置中尝试写入 /var/log/journal/ 下的文件,而 journald 正在等待 rsyslog 启动完成才释放 /dev/log —— 此时需调整 After= 和 Wants= 顺序,或改用 omjournal 模块替代文件输出










