本文要点
- journalctl 是 systemd 的统一日志查询命令,
-b看本次启动日志、--list-boots列出全部启动历史,本文实测机当前只有 2 次启动记录 - 排查"某个服务今天干了啥"用
-u按服务过滤,再配合--since/--until锁定时间范围,比翻/var/log/syslog高效得多 - 只关心异常用
-p err过滤日志优先级,本文实测机历史错误集中在 sshd 的kex_protocol_error与连接被重置,是典型的扫描与握手残留 - 日志按结构化二进制存储,
-o json-pretty能导出字段供脚本解析;--disk-usage看占用、--vacuum-size按体积清理,实测机日志共占 165.4M - 本文全部命令在 Ubuntu 24.04(journald 默认开启)真实执行,无需安装任何额外软件
journalctl 是什么:systemd 的统一日志
传统 Linux 把日志散落在 /var/log 下多个文件里:syslog、auth.log、messages,每个软件一个文件、格式各不同。systemd 时代引入 journald,把内核、systemd 自身和各服务的日志统一收集进二进制日志库,journalctl 就是查询这个日志库的命令行前端。
journald 的优点不只是"集中":
- 默认记录更全:内核消息(dmesg 的内容)、systemd 启动过程、每个 unit 的输出都在里面
- 结构化管理:每条日志除了时间与消息文本,还附带 PID、服务名、源码位置等字段,可精准过滤
- 支持逻辑过滤:按服务、按时间、按优先级、按进程,组合条件一条命令完成
发行版几乎都默认启用 journald。在 Ubuntu 24.04 上,journalctl 开箱即用。
查看启动历史:--list-boots
机器重启过几次、每次启动起止时间,用 --list-boots 一目了然。它把每次开机当作一个编号(boot id)列出来,最新一次是索引 0:
journalctl --list-boots
输出有 4 列:IDX(索引,最新启动是 0,往上是 -1、-2……)、BOOT ID(本次启动的唯一标识)、FIRST ENTRY/LAST ENTRY(本次启动日志的起止时间)。上面这台实测机只有两次启动:-1 是 8 月 2 日一次很短的启动(18:23 到 18:42,约 19 分钟),0 是当前这次,从 8 月 2 日一直跑到 9 月 2 日。
索引最大的用处是配合 -b 指定看哪一次启动的日志,比如 journalctl -b -1 回看上一次启动。
查看本次启动日志:-b 与 -n
-b(boot)不带参数默认看当前这次启动的日志,带索引看对应那一次。配合 -n 只取末尾 N 条,是最常用的"看最近发生了什么":
journalctl -b -n 6-b -n 6 相当于"本次启动、只看最后 6 条"。这类输出每行格式是 月 日 时:分:秒 主机名 进程[PID]: 消息,比如上面实测机的最后几条正是刚建立的 SSH 会话与 systemd-logind 记录的登录会话,时间线清晰,非常方便确认"刚才那台机器上发生了什么"。
如果还想看得更少些,journalctl -b -n 20 控制条数;完全退出滚动查看按 q。
按服务过滤:-u
日志库里混着几十个服务的记录,只想看某一个时用 -u(unit)指定服务名,比如只看 cron:
journalctl -u cron -b-u 可以叠加(-u cron -u ssh),也支持 * 通配(如 -u "php*")。这台实测机上 cron.service 每过 60 秒就会被唤醒一次执行定时任务,所以它的日志非常密集。
按时间过滤:--since 与 --until
时间过滤是排查"某个时刻发生了什么"的利器,和 -u 组合后威力最大。--since 从某时间点开始,--until 到某时间点结束,二者可单用可组合。下面这条把 cron 服务、最近 1 小时两个条件合在一起:
journalctl -u cron --since "1 hour ago" -n 5
可以看到 CRON[3738884]、CRON[3738885] 等进程逐行记录:session 打开、执行 CMD (...)、session 关闭,其中就有提前放在 crontab 里每分钟执行的 /usr/local/bin/cron-demo.sh。时间写法很灵活:"1 hour ago"、"today"、"2026-09-01 20:00" 都可以,也支持 --since -10min 这类相对写法。
把 --since "1 hour ago" 换成 --since "yesterday" --until "today",就只查昨天一整天的记录。
按优先级过滤:-p
日志按严重程度分 0~7 级(emerg 到 debug),日常排查不想被 INFO 刷屏时用 -p 指定最低级别。-p err 表示"只看 err 及以上(err、crit、alert、emerg)":
journalctl -p err -b -n 5
这台实测机过滤出来的错误几乎全是 sshd 的:kex_protocol_error: type 20 seq 6 [preauth]、kex_exchange_identification: read: Connection reset by peer。这些发生在密钥交换握手阶段(preauth)的报错,一般是端口扫描器或异常客户端留下的握手残留,不是配置问题——知道"日志级别 + 错误分布"就能快速判断是不是需要处理。
内核日志:-k
内核消息以前用 dmesg 看,journald 也一并收集了。-k 只看内核日志,配合 -b 和 -n 用来查驱动、硬件、网络设备相关问题:
journalctl -k -b -n 10实测机上能看到 docker 网络设备的 veth 注销、br0 桥接端口状态变化等内核消息。
实时跟踪:-f
和 tail -f 一样,-f(follow)持续跟随新日志输出。重启服务、触发一次报错时实时观察最直观:
journalctl -f -u nginx上面的命令只跟踪 nginx 服务的实时输出;journalctl -f 不带 -u 则是全量实时滚动。配合时间过滤还能只看"从现在起"的记录。
结构化输出:-o json
journal 每条日志都有结构化字段,用 -o json-pretty 能导出成 JSON 方便脚本解析(_EXE、_CMDLINE、SESSION_ID、MESSAGE 等):
journalctl -o json-pretty -b -n 1输出形如:
{
"_COMM": "systemd-logind",
"_CMDLINE": "/usr/lib/systemd/systemd-logind",
"_HOSTNAME": "demo",
"_EXE": "/usr/lib/systemd/systemd-logind",
"MESSAGE": "Removed session 44393.",
"PRIORITY": "5",
"SESSION_ID": "44393",
"SYSLOG_IDENTIFIER": "systemd-logind"
}文本日志里看不到的元数据(调用进程、session 号、代码位置)在 JSON 里都是独立字段,接监控告警或写日志分析脚本时很有用。
日志占用与清理:--disk-usage 与 --vacuum-size
journal 日志是二进制的,不清理会一直累积。先看占了多少:
journalctl --disk-usage实测机输出 Archived and active journals take up 165.4M in the file system.(归档 + 活动日志共 165.4M)。按体积清理到目标值:
journalctl --vacuum-size=200M--vacuum-size 把总占用压到 200M 以内(优先删旧的);另外还有按时间清理的 --vacuum-time=7d(只留 7 天)。这只是清理本次,要限制日志长期增长,改 /etc/systemd/journald.conf 里的 SystemMaxUse(如 SystemMaxUse=500M)并重启 systemd-journald 即可。
结语
journalctl 把"日志分散在不同文件"的旧局面收敛成一条命令:-b 看启动、-u 按服务、--since/--until 按时间、-p 按级别、-o json 导出结构化数据。排查系统问题时,先 -p err --since "1 hour ago" 扫一遍异常,再用 -u 定位具体服务,通常比从头翻日志文件快得多。
想进一步了解 systemd 的服务管理与定时任务,可参考本站的 systemd 服务管理:从 service 单元到 timer 定时与 journalctl 日志排查。
评论 (0)
暂无评论,快来抢沙发吧!