journalctl 日志查询指南:过滤、输出格式与存储管理
systemd 系统的日志都归 journald 管,但几十万条记录怎么查?本文详解 journalctl 的时间/服务/级别过滤、JSON 输出、实时跟踪与磁盘清理方法,并给出将 journal 日志接入观测云集中分析的路径。
journalctl 是 systemd 日志系统(journal)的官方查询工具,用于检索由 journald 守护进程以二进制格式集中收集的内核、服务与用户态进程日志。 与传统文本日志不同,journal 是结构化二进制日志——查得快的关键不是 grep,而是掌握 journalctl 的过滤语法。
核心要点速览
- journald 统一收集内核、systemd 服务和用户进程的日志,以结构化二进制格式存储;
- 最常用的三组过滤:
-u按服务、--since/--until按时间、-p按级别; -f实时跟踪、-o json结构化输出、-e直接跳到末尾,是排障高频组合;- journal 默认会持续占用磁盘,需用
--vacuum-size/--vacuum-time或 journald.conf 上限参数控制; - 多机排障需要保留主机与服务字段,集中查询时仍按时间窗缩小范围。
先解决权限:为什么看到的日志不全?
普通用户默认只能看到自己进程的日志。执行 journalctl 若提示"Users in groups 'adm', 'systemd-journal' can see all messages",把用户加入特权组并重新登录即可:
sudo usermod -a -G systemd-journal <用户名>
基本查询:从全量到精准过滤
不带参数执行 journalctl,会按时间从旧到新列出全部条目(自动进入分页器)。加上 --no-pager 可关闭分页,方便管道给 grep/awk 处理。
真正实用的是过滤组合:
# 按服务过滤(-u 可重复指定多个单元)
journalctl -u ssh.service -u nginx.service
# 按时间过滤(支持自然语言)
journalctl --since "2026-08-25 00:00:00" --until "2026-08-26 00:00:00"
journalctl --since "1 hour ago" # 最近一小时
journalctl --since yesterday # 昨天
# 按优先级过滤(emerg=0 … debug=7,指定级别即含更高级别)
journalctl -p err # err 及以上(err/crit/alert/emerg)
# 只看本次启动以来的日志
journalctl -b
排障高频组合:
journalctl -u myapp.service -f # 实时跟踪某服务
journalctl -u myapp.service -e # 直接跳到最新
journalctl -p warning --since today # 今天所有告警及以上
定制输出:给机器看还是给人看?
journal 每条日志内部是结构化字段,journalctl -o 可以换"皮肤":
| 输出格式 | 适用场景 |
|---|---|
short(默认) |
传统 syslog 样式,人读 |
json / json-pretty |
完整字段输出,供程序解析或接入管道 |
verbose |
查看全部字段(含 _PID、_COMM 等内部字段) |
cat |
只输出消息正文 |
例如 journalctl -u ssh -o json-pretty,能看到 MESSAGE、PRIORITY、_HOSTNAME 等全部字段——这些字段也可以直接用于过滤:journalctl _PID=1234、journalctl _COMM=sshd。
管好磁盘:journal 不是无底洞
先看当前占用:journalctl --disk-usage。
手动清理(需 sudo):
sudo journalctl --vacuum-size=500M # 缩到 500MB 以内
sudo journalctl --vacuum-time=1month # 删除一个月前的记录
长期方案是改 /etc/systemd/journald.conf 设置硬上限:
[Journal]
Compress=yes
SystemMaxUse=5G # 持久存储上限
RuntimeMaxUse=1G # 内存挂载存储上限
SystemMaxFileSize=100M # 单个 journal 文件上限
SystemMaxFiles=100
多机环境:journalctl 的天花板
跨主机排查同一服务时,需要把主机名、服务标识和时间一起保留。观测云的 Journald 采集器从 Linux systemd journal 读取结构化日志,可通过 units 和 priorities 限定服务与级别。
配置前确认 libsystemd 和 journal 读取权限,设置 journal 目录后重启 DataKit。先让目标服务产生一条测试日志,在平台上核对主机、服务、时间和消息,再扩大采集范围。是否读取历史记录由 tail_only 与游标配置决定。
总结
掌握 journalctl 的精髓就三句话:过滤用 -u/-p/--since,跟踪用 -f,控磁盘用 vacuum 与 journald.conf。跨主机排查时,把相同时间窗内的服务日志集中起来比较。
常见问题(FAQ)
Q:journalctl 和 /var/log/syslog 是什么关系?
在 systemd 系统上两者并存:journald 先收到日志,再转发给 rsyslog 写成文本 syslog。journal 是结构化二进制、字段更全;syslog 是纯文本、便于传统工具处理。空间紧张时可只保留其一。
Q:为什么重启后 journalctl 查不到历史日志?
说明 journal 用的是易失存储(/run/log/journal)。创建 /var/log/journal 目录或在 journald.conf 中设置 Storage=persistent,重启后日志即可持久保留。
Q:如何查看上一次启动的日志(比如系统崩溃前)?
用 -b 加负数偏移:journalctl -b -1 查看上一次启动,-b -2 上上次,配合 -p err 可快速定位崩溃前的错误。
Q:journalctl -f 和观测云日志查看器的实时模式有何区别?
-f 跟踪当前查询目标的新记录;平台查看器查询的是已采集上报的数据。集中查询前先确认需要的主机和服务已接入,数据范围与本地 journal 可能不同。
系列阅读:Linux 系统日志管理入门 | Linux 认证日志监控实战