Linux 系统日志管理与分析方法

2次阅读

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

Linux 系统日志管理与分析方法

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.confStorage= 是否设为 persistent(而非默认的 volatile
  • 改完记得重启服务:sudo systemctl restart systemd-journald,否则配置不生效
  • 即使开了持久化,SystemMaxUse=MaxRetentionSec= 仍会自动清理,比如设成 100M1month,超限或过期就删最老的文件,不是按天切片

分析日志时发现时间戳混乱或时区错乱

journalctl 默认显示本地时间,但底层日志以 UTC 存储。如果系统时区配置异常,或者远程服务器没同步时间,journalctl --since "yesterday" 这类相对时间就会偏差明显,甚至跨天。

  • 统一用 UTC 查:journalctl --utc --since "2024-05-20 00:00:00",避免时区干扰
  • 检查系统时间是否准确:timedatectl statusSystem clock synchronized: 是否为 yes,不是就运行 sudo systemctl restart systemd-timesyncd
  • 容器或 chroot 环境中,/etc/localtime 可能未挂载,journalctl 会 fallback 到 UTC,但显示时不标注,容易误判

日志时间不准这事,往往不是工具问题,而是时间源、时区、持久化三者没对齐。调的时候得一块儿看,不能只盯一个配置项。

text=ZqhQzanResources