快速定位 systemd 服务实时日志应使用 journalctl -u -f,避免依赖 /var/log/;需加 -f 实时跟踪、-u 精确服务、--since 防轮转丢失、--all 查截断长行,并用结构化过滤(如 -p err)替代盲目 grep。

怎么快速定位 systemd 服务的实时日志
直接用 journalctl -u <service-name> -f</service-name>,别先翻 /var/log/ 下的文件——很多现代服务(比如 nginx、docker)默认不写传统日志,全走 journald。
常见错误是加了 -n 100 就以为能“看到最新”,其实没 -f 就只是快照;漏掉 -u 则会混入内核或其它服务日志,干扰判断。
-
-u ssh比-u sshd更可靠——有些发行版单元名就是ssh.service - 加
--since "2 hours ago"比手动翻页更准,避免因日志轮转丢记录 - 如果服务刚挂过,加
--all才能看到被截断的长行(比如堆栈或 JSON 日志)
grep 日志时为什么总漏关键行
因为默认只匹配完整行,而错误常跨行出现(比如 Java 异常的 Caused by: 在下一行),或被日志框架加了前缀(如 [ERROR] 或时间戳)干扰模式匹配。
别直接 grep "timeout",先用 journalctl -u app | head -20 看真实格式,再决定要不要去前缀、是否要跨行。
- 用
journalctl -u app --no-pager | grep -A 2 -B 1 "Connection refused"抓上下文 - 匹配带颜色的日志?加
--no-color,否则grep会被 ANSI 转义符卡住 - 想排除健康检查日志?用
grep -v "GET /health",但注意有些服务把错误也打在/health响应体里,得看 body
服务起不来,systemctl status 只显示 failed 怎么办
systemctl status 只展示最近一次启动的摘要,真正原因藏在 journalctl 的启动阶段日志里——尤其是 ExecStart= 对应的进程刚 fork 就退出时,错误往往只在启动瞬间输出。
必须加 --boot 和 -o short-precise:前者确保查的是当前 boot 的日志(不是上一次崩溃残留),后者让时间戳精确到微秒,方便对齐进程生命周期。
- 先运行
systemctl show -p ExecStart <service></service>确认实际执行命令,再手动跑一遍,看是否缺环境变量或权限 - 如果报
Failed at step EXEC spawning,大概率是二进制路径错、动态库找不到,或SELinux拦截(查ausearch -m avc -ts recent) -
systemctl reset-failed <service></service>不解决根本问题,只是清状态——别把它当修复手段
日志太多,怎么筛出真正影响服务可用性的条目
不是所有 ERROR 都致命。关注三类信号:exit code 非零、panic/segfault、以及反复出现的连接类失败(如 connect: connection refused)。其余多数是业务级告警,可延后处理。
用 journalctl 的结构化过滤比纯文本 grep 更稳:它支持按优先级(-p err)、进程 ID(_PID=1234)、甚至容器 ID(_CONTAINER_NAME=web)筛选。
-
journalctl -u app -p err --since "5 minutes ago"比grep ERROR准,因为有些日志把 INFO 写成大写 - 发现大量
connection reset by peer?别急着查服务本身,先用ss -tuln | grep :端口确认端口真在监听 - 日志里频繁出现
Too many open files?立刻查cat /proc/<pid>/limits | grep "Max open files"</pid>,别只调ulimit配置
最麻烦的其实是日志没报错但服务没响应——这时候得切到网络层,用 tcpdump 或 strace -p <pid> -e trace=sendto,recvfrom</pid> 看它到底收没收到请求。










