journalctl查不到服务日志需依次确认unit名称正确、服务已启用、日志未被轮转清理;检查journald存储配置(storage=none则日志仅存内存);排查终端编码与字符集匹配问题;结合dmesg和coredump定位崩溃详情;用时间范围和字段过滤高效检索。

journalctl 查不到服务日志?先确认 unit 名称和日志留存策略
systemd 服务日志默认由 journalctl 管理,但查不到不等于没输出——常见原因是 unit 名称写错、服务未启用、或日志已被轮转清理。
-
journalctl --list-units --type=service看服务是否在 systemd 中注册(注意拼写,比如nginx.service不是nginx) - 刚启动的服务可能还没刷入 journal,加
-o json-pretty和--since "1 minute ago"缩小范围 -
journalctl --disk-usage查当前日志占多少空间;若为 0 或极小,说明Storage=none在/etc/systemd/journald.conf中被设了,日志只存在内存里,重启即丢 - 临时启用持久化:改
Storage=persistent,再运行sudo systemctl kill --signal=SIGUSR1 systemd-journald重载配置
grep 出来全是乱码或空行?终端编码和 journal 字符集不匹配
日志里含中文、emoji 或特殊符号时,journalctl 默认按 UTF-8 解析,但终端 locale 或管道处理会破坏原始字节流。
- 先检查
locale输出是否含UTF-8(如LANG=en_US.UTF-8),不是就临时设:LANG=C.UTF-8 journalctl -u nginx.service - 避免用
grep直接筛二进制内容:加--all参数确保显示所有字段(包括 _HOSTNAME、_PID),再用awk或jq处理更稳 - 如果日志本身含控制字符(比如某些 Python logging 配置用了
\r刷屏),加--no-hostname --no-pager防止终端渲染干扰
服务明明 crash 了,journalctl 却没看到 segfault 或 exit code?得看内核日志和 coredump
用户态进程崩溃时,systemd 可能只记录 “main process exited, code=killed, status=11/SEGV”,但具体堆栈不在 journal 里——它被内核或 systemd-coredump 拦截了。
- 查内核消息:
dmesg -T | grep -i "segfault\|killed process",注意时间戳是否比 journal 早几秒 - 确认 coredump 是否启用:
systemctl is-enabled systemd-coredump;若为 disabled,sudo systemctl enable systemd-coredump并检查/proc/sys/kernel/core_pattern - core 文件默认存于
/var/lib/systemd/coredump/,用coredumpctl info <code>your-binary-name直接读取上下文,比翻日志快得多 - 某些容器化部署会禁用 coredump(如 Docker 的
--ulimit core=0),这时只能靠strace -f -e trace=signal提前挂载抓信号
日志量太大卡住 terminal?别硬翻,用 time-range + field filter 快速定位
线上服务跑几天后,journalctl -u xxx 可能返回几十万行,less 都卡死。关键是跳过“全量拉取”这个动作。
- 用
--since "2024-05-20 14:30:00"和--until "2024-05-20 14:35:00"锁定故障窗口,哪怕只差一分钟,数据量常差两个数量级 - 过滤特定字段比
grep更准:journalctl _PID=12345 PRIORITY=3(3 是 ERR 级别),避免正则误匹配 - 导出结构化数据:
journalctl -u nginx --output=json | jq 'select(.MESSAGE | contains("502"))',比 shell 管道稳定,且支持嵌套字段筛选 - 如果频繁要查,把常用组合做成 alias,比如
alias jnerr='journalctl -p 3 --since "1 hour ago"'
真正难的不是查哪条日志,而是判断该信哪条——比如同一时间点,kernel 日志说 OOM killer 杀了进程,而应用日志却报 “connection timeout”,这时候得看谁先发生,而不是谁声音大。










