查服务启动失败需用 journalctl -u 服务名 --all --no-pager 查全过程日志,避免漏掉前置错误;failed to start 是结果,真实原因在之前几行;启用持久化存储(/var/log/journal)才能查重启前日志。

查服务启动失败的完整日志链
服务启动失败时,journalctl 默认只显示最近几条,容易漏掉前置错误(比如依赖单元未就绪、配置文件语法错、权限不足)。必须加 -u 指定服务名,并用 --all 和 --no-pager 确保不截断、不翻页:
-
journalctl -u nginx.service --all --no-pager—— 查 nginx 启动全过程,含 pre-start 脚本输出 - 若服务刚失败过,加
-n 100只看最后 100 行也够用;但首次排查建议不用-n,避免跳过关键上下文 - 注意:没加
--all时,journalctl默认过滤掉 debug 级别日志,而某些 systemd 单元(如systemd-networkd)的配置解析错误只打在 debug 级
定位“failed to start”背后的真实原因
看到 Failed to start MyService. 这类提示只是结果,真正原因往往在它之前几行。常见干扰项包括:
-
Unit myservice.service entered failed state.—— 这是 systemd 自己写的总结,不是原始错误 -
Starting MyService...后紧跟着Failed to start,说明进程 fork 后立刻退出,大概率是二进制路径错、ExecStart=参数拼写错,或主程序执行时 stdout/stderr 未重定向导致崩溃静默 - 出现
code=exited, status=217/USER—— 表示用户不存在或User=配置值非法,不是程序本身报错 - 出现
code=killed, signal=SEGV—— 真实崩溃,需结合coredumpctl info myservice进一步查
过滤出真正有用的启动阶段日志
服务启动涉及多个阶段(parse unit → load dependencies → run ExecStartPre → exec main),混在一起看效率低。用 --since 和 --until 锁定时间窗口,再用 grep 精筛:
-
journalctl -u sshd.service --since "2024-05-20 14:00:00" | grep -E "(Failed|error|denied|cannot|No such)"—— 快速抓异常关键词 -
journalctl -u docker.service -o json | jq 'select(.MESSAGE | contains("failed") or .PRIORITY == "3")'—— 用 JSON 格式 +jq做结构化过滤(需先确认 journal 存储格式支持,journalctl --disk-usage可查) - 避免用
journalctl | grep "error"全局搜——很多无关单元(如 udev、bluetooth)也会打 error 日志,噪音极大
为什么重启后查不到上次失败日志?
默认 journal 日志保存在内存(/run/log/journal),重启即清空。要查历史失败记录,必须启用持久化存储:
- 创建目录:
sudo mkdir -p /var/log/journal - 重启 journald:
sudo systemctl kill --signal=SIGUSR1 systemd-journald(比restart更安全,不中断正在写日志的进程) - 验证:
journalctl --disk-usage应显示非零值;ls /var/log/journal/*/system.journal应有文件 - 注意:即使启用了持久化,旧日志也可能被轮转删除(
/etc/systemd/journald.conf中MaxRetentionSec=或SystemMaxUse=限制)
没开持久化时,唯一能抢救的办法是立刻运行 journalctl --list-boots,看上一次 boot 的 ID,然后用 journalctl -b -1 -u xxx 尝试读取(仅当上次 boot 的日志尚未被刷出内存时有效)。











