暗色模式

journalctl 系统日志:从启动日志查询到按服务与时间过滤排查

技术教程
2026-09-02
15
0
本文要点
  • 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 下多个文件里:syslogauth.logmessages,每个软件一个文件、格式各不同。systemd 时代引入 journald,把内核、systemd 自身和各服务的日志统一收集进二进制日志库,journalctl 就是查询这个日志库的命令行前端。

journald 的优点不只是"集中":

  • 默认记录更全:内核消息(dmesg 的内容)、systemd 启动过程、每个 unit 的输出都在里面
  • 结构化管理:每条日志除了时间与消息文本,还附带 PID、服务名、源码位置等字段,可精准过滤
  • 支持逻辑过滤:按服务、按时间、按优先级、按进程,组合条件一条命令完成

发行版几乎都默认启用 journald。在 Ubuntu 24.04 上,journalctl 开箱即用。

查看启动历史:--list-boots

机器重启过几次、每次启动起止时间,用 --list-boots 一目了然。它把每次开机当作一个编号(boot id)列出来,最新一次是索引 0

journalctl --list-boots

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 日志

可以看到 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_CMDLINESESSION_IDMESSAGE 等):

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 日志排查

发表评论

暂无评论,快来抢沙发吧!