跳转到内容
启涵的小破站
返回

systemd journal 使用指北

服务器出问题了,很多人第一反应还是去翻 /var/log。传统日志文件当然要看,但 systemd 时代大部分服务已经把日志交给 journald 了。journalctl 用得怎么样,很多时候决定了排查有多快。

这篇聊聊 journal 的几个实用场景,大部分是我自己排查时常用的路子。


基础

先跑一下看看有什么:

journalctl

默认调 less 翻页,按时间倒序,最新的在最下面。想看最新的日志可以直接看尾部:

journalctl -n 50

tail -n 差不多。

想实时跟踪新日志就加 -f

journalctl -f

tail -f 一样,停在原地等新日志出现。调试服务时可以开着它。

按时间查日志

journal 的一大好处:时间筛选比翻文件精准得多。

# 查今天的
journalctl --since today

# 查某个时间段
journalctl --since "2026-08-10 14:00" --until "2026-08-10 16:00"

# 查最近 30 分钟
journalctl --since "30 min ago"

格式很灵活,“yesterday""-1h""2026-08-10” 都能识别。比去 /var/log 里翻 messages 文件方便太多了。

按服务/单元查

这是我最常用的场景。某个服务挂了,直接看它的日志:

journalctl -u nginx.service
journalctl -u ssh.service --since today
journalctl -u docker.service -n 50 -f

多个单元也能一起查:

journalctl -u nginx.service -u php-fpm.service

看两个服务的日志交错输出,排查联动问题的时候很方便。

按优先级过滤

日志有级别,从 0(emerg)到 7(debug)。只查错误以上的:

journalctl -p err -b

查警告和错误:

journalctl -p warning

数字也行,-p 3 等价于 -p err

一般线上排查从 -p err 开始,过滤掉 info 级别的噪声,直接看异常。

按本次启动查

每次系统启动的日志是分开存放的。查当前启动的:

journalctl -b

查上一次启动的:

journalctl -b -1

依次类推,-b -2 是上上次。服务器重启后想对比之前的状态,用这个最快。没有 journal 的话你得去 /var/log 里翻轮转后的文件,远不如一个 -b -1 来得直接。


实战一:查某个 PID 的日志

知道某个进程的 PID,直接看它写了什么日志:

journalctl _PID=12345

也可以跟时间筛选结合:

journalctl _PID=12345 --since "5 min ago"

有些进程名也会记录,不过 _PID 是最确定的。

实战二:查内核日志

内核日志用 dmesg 当然可以,但 journal 也收了一份:

journalctl -k
journalctl -k -p err
journalctl -k -b -1

硬盘报错、驱动崩了、OOM killer 下手了,这些都能在 -k 里看到。以前得 dmesg | grep error,现在 journalctl -k -p err 一条搞定。

实战三:关联日志(按消息关联)

很多服务挂了不是单一原因,journal 有个挺好用的字段 _COMM,表示命令名:

journalctl _COMM=sshd
journalctl _COMM=nginx

更细的还可以查 _SYSTEMD_UNIT 之类的字段。用 -o verbose 可以看到每个日志条目携带的所有字段:

journalctl -u nginx.service -o verbose | head -50

输出里能看到 _PID _UID _GID _COMM _EXE 等各种元数据,这些都可以直接当过滤条件用。


日志持久化

默认 journald 日志存在内存里,重启后就没了。想持久化很简单:

mkdir -p /var/log/journal

或者直接编辑 /etc/systemd/journald.conf,把 Storage 设为 persistent

[Journal]
Storage=persistent

之后重启 journald:

systemctl restart systemd-journald

持久化后日志会保留在 /var/log/journal/ 下,按机器 ID 分目录存放。好处是真出问题的时候重启了也能查上次的日志。

日志大小控制

journal 日志如果不控制会一直涨。默认是限制在文件系统的 10% 容量,但也可以自己设:

# 查看当前限制
journalctl --disk-usage

# 限制最大 500M
journalctl --vacuum-size=500M

# 保留最近 7 天
journalctl --vacuum-time=7d

# 保留最近 1000 条
journalctl --vacuum-files=1000

也可以在 journald.conf 里做永久配置:

SystemMaxUse=500M
MaxFileSec=7day

新机器最好都配上这个,省得哪天硬盘被日志撑爆了才想起来。

日志导出

想把日志拷到别的机器上分析,journal 支持好几种导出格式:

# 导出为普通文本
journalctl -u nginx.service > nginx.log

# 导出为 JSON
journalctl -u nginx.service -o json > nginx.json

# 导出为可移植的 journal 文件
journalctl -u nginx.service -o export > nginx.journal

导出格式里 JSON 最好用,每行一条,字段清晰,写脚本处理很方便。

性能提示

journal 的数据库文件在 /var/log/journal/ 下,查日志时其实是在查一个二进制数据库。日志量大的时候,加上时间筛选可以让查询快很多——不带 --since 的话可能要从第一条日志开始扫,几十 GB 的日志量够你等一会儿。

另外,-o cat 只输出消息内容本身,不带时间戳和主机名这些元数据,想批量处理文本日志时提速明显:

journalctl -u nginx.service -o cat --since today

上面这些用法不用全记住。先记住几个最常用的就好:-u 查服务、-n 看尾部、-f 跟踪、-p err 过滤错误、--since 筛时间。这几个组合能覆盖绝大部分排查场景。

剩下的遇到具体问题再查 manual 就行,journalctl(1) 的文档写得不错,比很多项目文档清楚。


分享本文:

上一篇
DN42 网络探索指南
下一篇
Linux 进程管理实用指南

加载评论区中...