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 查询时识别到的当前启动,不等于“最近一条日志”。如果机器查看的是另一台主机导出的 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 负责限定优先级。

# 只看本次启动中 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 最有价值的地方不是省了两个字符,而是给排障建立了稳定的时间边界:先确定是哪次启动,再叠加服务、时间和优先级条件。这样即使日志很多,也能把“这次启动发生了什么”与“机器以前发生过什么”分开讨论。
-
364 收藏
-
Golang · Go教程 | 5个月前 | 超时控制 · 故障排查 · Go教程 · 后端工程 · Golang实战 · HTTP客户端 · golang Go 性能优化 net/http context Transport 超时 http.Client 生产实践205 收藏
-
Golang · Go教程 | 4个月前 | 并发 · HTTP · 性能优化 · 故障排查 · Go教程 · Go Goroutine 连接复用 pprof http.Client close Response.Body201 收藏
-
339 收藏
-
Golang · Go教程 | 3个月前 | golang · JSON · 故障排查 · Go教程 · 接口设计 · JSON Go 接口兼容性 DisallowUnknownFields 严格解码174 收藏
-
文章 · linux | 18分钟前 | linux运维 · 文件系统 · Linux 文件句柄 name_to_handle_at open_by_handle_at file_handle mount_id340 收藏
-
351 收藏
-
490 收藏
-
文章 · linux | 25分钟前 | linux运维 · 故障排查 · 服务治理 · Linux systemd 故障恢复 服务重启 RestartSec StartLimit Restart RestartSteps312 收藏
-
132 收藏
-
文章 · linux | 29分钟前 | linux运维 · Linux cgroup v2 frozen cgroup.freeze cgroup.events populated 进程层级 运维监控332 收藏
-
481 收藏
-
313 收藏
-
165 收藏
-
329 收藏
-
438 收藏
-
263 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习