journalctl 是日志查询工具而非错误触发器,需配合脚本或监控系统实现异常检测;应聚焦内核级严重事件、服务启动失败链及单元状态异常,并通过结构化解析与 systemd 原生机制提升可靠性。

journalctl 本身不是“错误触发器”,它不主动监控或告警,而是一个日志查询与检索工具。所谓“系统级错误触发器”,实际是指利用 journalctl 配合其他机制(如脚本、定时任务、外部监控系统)来检测并响应异常日志模式。真正的触发动作必须由你定义逻辑——比如发现连续5条 PRIORITY=3(err)且含关键词 "failed to bind" 的服务日志,才执行告警或重启。
识别真正需关注的系统级错误日志
不是所有 -p err 输出都代表故障。关键看来源和上下文:
-
内核级严重事件:用
journalctl -k -p emerg或-p crit查看硬件故障、OOM killer、panic 前兆 -
服务启动失败链:
journalctl -u nginx.service --since "10 min ago" | grep -i "failed\|cannot\|refused"比单纯-p err更精准 -
systemd 单元状态异常:优先查
journalctl -u nginx.service -b(本次启动),再比对journalctl -u nginx.service -b -1(上一次启动),确认是否为偶发还是持续性崩溃
用 journalctl 搭建轻量级错误捕获逻辑
无需部署复杂监控平台,一个简单脚本能完成基础触发:
- 每5分钟执行:
journalctl -u docker.service --since "5 min ago" -p err | grep -q "connection refused" && echo "$(date): Docker API 不可达" | mail -s "Docker 异常" admin@example.com - 注意避免重复告警:加
touch /tmp/docker_alerted_$(date -d '5 min ago' +%Y%m%d_%H)锁文件,或用journalctl --cursor=...实现增量读取 - 生产环境建议用
--output=json输出,再用jq提取_SYSTEMD_UNIT、PRIORITY、MESSAGE字段做结构化判断,避免正则误匹配
避免常见误判陷阱
很多“看起来像错误”的日志其实是正常行为:
-
systemd[1]: Started Network Manager.后紧跟NetworkManager[xxx]: <info> ...</info>是启动成功,不是错误 -
Failed to connect to bus: No such file or directory出现在容器内或非 systemd 环境中,属于架构不匹配,不是系统故障 -
Connection refused可能只是上游服务短暂未就绪,需结合前后时间戳和重试次数判断是否真异常
配合 systemd 的原生机制提升可靠性
与其在日志里“大海捞针”,不如让错误主动上报:
- 在 service 文件中设置
Restart=on-failure和StartLimitIntervalSec=60,让 systemd 自动应对崩溃 - 用
ExecStartPost=/usr/local/bin/log-alert.sh在服务启动后立即检查状态并记录到 journal,形成可追溯的决策日志 - 启用
Storage=persistent并配置SystemMaxUse=512M,确保关键错误日志不会因磁盘满而被自动清理

















