journalctl -u nginx -n 100systemd 服务的日志首选入口,-n 100 看最近 100 行。
约 1189 字大约 4 分钟
2026-05-14
排查问题,一大半时间花在“看日志”上。但 Linux 上的日志不止一个地方:systemd 的 journal、传统的 /var/log 文本文件、应用自己的日志。先搞清“什么日志在哪里”,才不会对着一个文件干瞪眼,而真正的线索在另一处。
弄清 journal、/var/log 传统日志、应用自有日志三者的关系,知道遇到问题该去哪里找。
journalctl -u nginx -n 100systemd 服务的日志首选入口,-n 100 看最近 100 行。
journalctl -u nginx -f类似 tail -f,新日志滚动出现,复现问题时用。
journalctl -b -p err-b 限本次启动,-p err 只看错误及以上级别。
tail -f /var/log/app.log应用写在 /var/log 下的文本日志,仍用 tail/grep。
| 日志来源 | 在哪里 | 怎么看 |
|---|---|---|
| systemd journal | 内核 + 所有 systemd 服务的输出 | journalctl |
| 传统系统日志 | /var/log/(syslog、auth.log、dmesg 等) | cat / tail / grep |
| 应用自有日志 | 应用自己的目录,如 /var/log/nginx/、/opt/app/logs/ | tail / grep,或应用自带工具 |
关键判断:如果服务是 systemd 管理的,第一选择永远是 journalctl -u 服务名。很多人习惯去 /var/log 翻文件,结果那个服务根本没往文本文件写,所有输出都进了 journal。
journal 把所有服务的日志集中存起来,查的时候靠两个维度切:
按服务——-u 指定 unit:
journalctl -u nginx # 只看 nginx
journalctl -u nginx -u php-fpm # 同时看两个,按时间交织按时间——-b 本次开机、--since / --until 指定区间:
journalctl -u nginx --since "10:00" --until "10:30"
journalctl -u nginx --since "1 hour ago"
journalctl -b -p err # 本次开机的 error 及以上两个维度叠起来用,几百万行日志能瞬间缩到几十行。更多用法见 journalctl 速查。
现代应用(尤其是容器里的)越来越倾向于把日志直接打到标准输出,而不是写文件。如果它由 systemd 管理,stdout 会被 journal 自动收走——所以还是 journalctl -u。如果它在容器里,就是 docker logs / kubectl logs。找不到日志文件时,先想一想:它是不是根本没写文件。
/var/log 下的日志由 logrotate 定期切割:app.log 是当前的,app.log.1、app.log.2.gz 是旧的。排查“几天前发生的事”,可能要去翻 .1 或解压 .gz。journal 也有大小 / 时间上限,太老的会被清掉——journalctl --disk-usage 看它占了多少。
日志只读,别在排查时去“清”它
排查问题时日志是证据,只该读、不该改。不要为了腾空间在排查途中删日志或清空文件——线索没了就回不来了。真要清理空间,见 磁盘空间排查,且优先让 logrotate 或 journalctl --vacuum-time 来做,而不是手动 rm 或 > file。手动清空正在被进程写的日志文件,还可能导致空间不释放(见 inode、硬链接与软链接)。
| 误区 | 更稳妥的做法 |
|---|---|
systemd 服务出问题只去 /var/log 翻文件 | 优先 journalctl -u 服务名,很多服务只写 journal |
| 找不到日志文件就以为没日志 | 应用可能打到 stdout,被 journal 或容器运行时收走 |
| 只看当前日志文件,忽略 rotate 出的旧文件 | 翻 .1、解压 .gz,或用 journalctl 的时间区间 |
| 排查时顺手清日志腾空间 | 日志是证据,排查中只读不改;清理交给 logrotate |
版权归属:Shuo Liu