journalctl 实时日志卡住是因默认不跟随,需加 -f;普通用户无权限查系统日志,应加 sudo 或加入 systemd-journal 组;日志未持久化导致重启后丢失,需配置 storage=persistent 并重启 journald。

journalctl 查看实时日志时卡住或没输出
默认情况下 journalctl 不会自动跟随新日志,看起来像“卡住”;加上 -f 才能实时滚动。但更常见的问题是权限——普通用户看不到系统级服务日志,直接执行 journalctl -u sshd -f 可能返回空或报错 No journal files were found。
- 先确认日志存在:
sudo journalctl --disk-usage看是否启用持久化存储(/var/log/journal/目录是否存在) - 非 root 用户想查服务日志,要么加
sudo,要么把用户加入systemd-journal组:sudo usermod -aG systemd-journal $USER,然后重新登录 -
journalctl -b只查本次启动的日志,journalctl --since "2 hours ago"更适合排查近期问题,避免翻太多历史
grep 过滤日志时匹配不到关键词
不是 grep 不好用,是日志内容结构导致的:systemd 日志每行包含时间戳、服务名、PID 等前缀,纯 grep "Error" 容易漏掉真正带错误信息的行;而且默认输出是“结构化”的,journalctl 的字段分隔符不是空格,直接管道给 grep 会误判上下文。
- 优先用
journalctl原生过滤:journalctl -p err(只看 error 级别及以上),journalctl _SYSTEMD_UNIT=nginx.service(精确到 unit) - 真要用
grep,加-o或配合--output=cat去掉元数据:journalctl --output=cat | grep -i "connection refused" - 注意大小写和空格:某些日志里错误信息藏在引号里或换行后,比如
"failed to connect"后面换行跟Connection refused,单行grep就抓不到
日志轮转后查不到旧记录
linux 默认不开启日志持久化,重启后 journalctl 就只能看到本次启动后的日志。很多用户以为“日志被删了”,其实是根本没落盘。
- 检查配置:
/etc/systemd/journald.conf中Storage=是否设为persistent(而非默认的volatile) - 改完记得重启服务:
sudo systemctl restart systemd-journald,否则配置不生效 - 即使开了持久化,
SystemMaxUse=和MaxRetentionSec=仍会自动清理,比如设成100M和1month,超限或过期就删最老的文件,不是按天切片
分析日志时发现时间戳混乱或时区错乱
journalctl 默认显示本地时间,但底层日志以 UTC 存储。如果系统时区配置异常,或者远程服务器没同步时间,journalctl --since "yesterday" 这类相对时间就会偏差明显,甚至跨天。
- 统一用 UTC 查:
journalctl --utc --since "2024-05-20 00:00:00",避免时区干扰 - 检查系统时间是否准确:
timedatectl status看System clock synchronized:是否为yes,不是就运行sudo systemctl restart systemd-timesyncd - 容器或 chroot 环境中,
/etc/localtime可能未挂载,journalctl会 fallback 到 UTC,但显示时不标注,容易误判
日志时间不准这事,往往不是工具问题,而是时间源、时区、持久化三者没对齐。调的时候得一块儿看,不能只盯一个配置项。