登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

journalctl -b 怎样筛选本次启动日志

来源:17golang原创

时间:2026-11-15 00:42:01 311浏览 收藏

我排查 Linux 启动问题时,最先遇到的通常不是“没有日志”,而是日志太多:当前启动、上一次启动、服务自己的记录和内核消息混在一起,凭肉眼翻很容易把时间线看错。journalctl -b 的作用,就是把查询范围收窄到某次启动;不写具体 ID 时,通常就是当前启动。

官方文档:https://www.freedesktop.org/software/systemd/man/latest/journalctl

只看本次启动,先用 journalctl -b;要看前一次启动,用 journalctl -b -1;要进一步缩小范围,再叠加 -u 服务名、--since、--until 和 -p err。如果历史启动根本不存在,先检查 journal 是否持久化以及当前用户是否有权读取系统日志。

-b 为空时为什么是本次启动

-b 是 --boot 的短选项。官方语义是给查询增加一个 _BOOT_ID= 匹配条件;参数为空时显示当前启动的记录。因此,下面两条命令表达的是同一个排查起点:

# 只查看当前这次启动产生的 journal 记录
journalctl -b

# 使用长选项写出同样的启动范围,便于放进排障脚本
journalctl --boot
journalctl、-b、当前启动、boot ID 和历史启动之间的静态关系
图1:journalctl 启动范围与 boot ID 关系图;这是静态说明图,不是终端截图或运行证据。

这里的“当前”是 journalctl 查询时识别到的当前启动,不等于“最近一条日志”。如果机器查看的是另一台主机导出的 journal,或者通过 --directory= 指定了其他日志目录,当前启动的相对位置也要结合实际日志内容判断。

我一般会在现场先加上 --no-pager,避免输出进入分页器后忘记自己正在看哪一段:

# 关闭分页器,让当前启动日志直接输出给管道或文件
journalctl --no-pager -b

用 --list-boots 选择历史启动

需要比较重启前后的差异时,先列出 journal 已经保存的启动记录:

# 列出启动相对编号、boot ID,以及每次启动记录的起止时间
journalctl --list-boots

--list-boots 会给出相对启动编号、boot ID,以及该启动对应的第一条和最后一条消息时间。常见的相对写法是 -b -1 查看上一次启动,-b -2 查看再前一次;-b 0 指向最新启动,省略参数的 -b 也通常落在当前启动。

如果我需要把一次排障记录交给别人,通常会把完整 boot ID 一起记下来,而不是只写“上一次启动”。相对编号会随着新启动产生而变化,完整 ID 更适合在同一批归档日志里复用:

# 用完整 boot ID 锁定一轮启动;ID 应替换成 --list-boots 输出中的真实值
journalctl --boot=0123456789abcdef0123456789abcdef --no-pager

命令中的 32 位十六进制字符串只是格式示意,不代表某台机器的真实 ID。不要把示例值直接当成查询条件。

把启动范围与服务和时间叠加

只写 -b 适合建立全局印象,真正定位服务故障时还要增加条件。journalctl 的筛选条件可以叠加:启动范围负责限定哪一轮开机,-u 负责限定 systemd unit,时间选项负责限定时段,-p 负责限定优先级。

journalctl 启动范围、服务、时间、优先级与日志存储权限的静态关系
图2:启动日志查询条件和可见日志边界图;这是静态说明图,不是终端截图或运行证据。
# 只看本次启动中 nginx.service 的错误及更高优先级消息
journalctl -b -u nginx.service -p err --no-pager

# 把范围缩到本次启动后的前十分钟,并保留完整时间格式
journalctl -b --since "10 min ago" --until "now" -o short-iso --no-pager

# 同时限定服务和时间,适合复盘某次重启后的启动窗口
journalctl -b -u demo-worker.service --since "today" --until "now" --no-pager

--since 表示从某个时间点(含)开始显示,--until 表示到某个时间点(含)为止。它们接受绝对时间,也接受 today、yesterday、now 和带正负号的相对时间。实际排障时,我会先用相对时间快速缩小范围,再把确认过的时间换成绝对时间写进记录。

优先级也有一个容易忽略的细节:写单个级别时,会包含该级别以及更严重的级别。例如 -p err 会覆盖 error 及更高严重度的消息;如果要看一个范围,可以写成 -p warning..err。这比先把所有日志导出再用文本工具过滤更容易保留 journal 的结构化条件。

为什么历史启动为空

如果 journalctl -b -1 没有结果,不要先把它判断为“命令不支持”。更常见的是历史日志没有被保存:systemd-journald 可以把日志放在持久化的 /var/log/journal,也可以放在重启后丢失的易失目录 /run/log/journal。Storage= 配置和目录是否存在,会影响这一选择。

# 查看 journald 相关配置,确认是否显式设置了 Storage
grep -R "^[[:space:]]*Storage=" /etc/systemd/journald.conf /etc/systemd/journald.conf.d 2>/dev/null

# 查看两类 journal 目录是否存在;这里只读目录状态,不修改系统
ls -ld /var/log/journal /run/log/journal 2>/dev/null

如果系统只使用易失存储,重启之后自然看不到更早的 boot;如果 journal 已经轮转或被清理,也不能从 --list-boots 里恢复不存在的记录。持久化设置的具体落地要结合发行版的运维规范,不能仅凭一条查询命令推断历史日志一定完整。

权限不足时先区分用户日志和系统日志

journalctl 默认只展示当前用户有权访问的日志。官方文档说明,系统 journal 和其他用户的 journal 通常需要 root,或需要属于发行版配置的日志读取组,例如 systemd-journal、adm、wheel。所以同一条 journalctl -b 在普通用户和管理员身份下,结果可能不同。

# 以管理员身份读取系统日志;只读查询不改变 journal 内容
sudo journalctl -b --no-pager

# 查询当前用户服务日志;--user 只面向当前用户的 systemd 服务
journalctl --user -b --no-pager

我会把“无记录”和“无权限看到记录”分开记录:先用合适权限重试,再判断是否真的没有历史启动。不要为了方便把整台机器的日志永久开放给所有用户;日志里可能包含路径、服务参数和其他运行上下文。

一套我会保留在值班手册里的组合

把常用条件按从宽到窄的顺序排列,复查时比较不容易漏掉范围:

目的命令组合主要回答的问题
建立当前启动全景journalctl -b --no-pager这次启动有哪些系统级记录
比较上一轮启动journalctl -b -1 --no-pager问题是否只在本次启动出现
定位服务错误journalctl -b -u 服务名 -p err该服务在本次启动为何失败
复盘启动窗口journalctl -b --since "10 min ago" --until now某段时间内发生了什么

如果需要把结果交给同事,我还会附上 --list-boots 的对应行、查询时的权限身份和日志目录范围。这样对方知道你看的究竟是哪次启动,而不是只拿到一段脱离上下文的文本。

几个容易混淆的问题

journalctl -b 是只看最近几分钟吗?

不是。它按启动边界筛选,会覆盖当前启动中 journal 已保存的记录;要限制最近几分钟,需要额外加 --since 或 -n 等条件。

-b -1 为什么有时查不到?

可能是上一轮启动没有被持久化、日志已被轮转,也可能是当前用户无权访问系统 journal。先运行 journalctl --list-boots,再区分这几种情况。

相对编号和 boot ID 该选哪个?

临时排查用 -1、-2 最快;要写入工单或复盘记录,建议保留完整 boot ID,因为相对编号会随新启动变化。

为什么同一条命令在 sudo 下内容更多?

system journal 的可见范围受权限控制。普通用户可能只能看到自己的 journal 或被授权的组日志,管理员身份能读取更多系统记录。

对我来说,-b 最有价值的地方不是省了两个字符,而是给排障建立了稳定的时间边界:先确定是哪次启动,再叠加服务、时间和优先级条件。这样即使日志很多,也能把“这次启动发生了什么”与“机器以前发生过什么”分开讨论。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>