journalctl 一句话版:journalctl -u <service> -f 实时跟踪服务日志,journalctl -u <service> -n 100 查看最后 100 行,journalctl --since "1 hour ago" 列出最近的所有日志。这三条覆盖 90% 的”这服务怎么又挂了”时刻。这份速查表的其余部分,是帮你省掉凌晨两点重读 man page 的复制粘贴模板——按单元、时间、优先级和开机次数过滤,外加防止日志吃掉磁盘的清理命令。下面每条命令在任何 systemd 发行版(Ubuntu、Debian、Fedora、Arch)上都能原样运行。
journalctl 是什么?为什么不直接读 /var/log/syslog?
老派 Linux 日志是写在 /var/log 下的纯文本文件——syslog、auth.log、messages。systemd 用日志(journal)取代了这套东西:一个由 systemd-journald 管理的二进制索引日志。普通 grep 读不了它;journalctl 是唯一的入口,作为回报,你可以按服务、时间、开机和严重级别过滤,不用玩正则杂技。
心智模型很简单:journal 存储一切,journalctl 是查询工具。服务不需要自己的日志文件——只要在 systemd 下运行,它写到 stdout/stderr 的所有内容都会自动进入 journal。这就是为什么 journalctl -u nginx 总能出结果,哪怕你完全不知道 nginx 把错误日志配在了哪里。
一个注意点:某些精简安装里 journal 是易失的(存在 /run,重启即清空),因为 /var/log/journal 不存在。修一次就好:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal 怎么查看日志的最后 100 行?
-n 把输出限制在最新的 N 行(默认 10 行):
journalctl -n 100 # 所有日志的最后 100 行
journalctl -u nginx -n 100 # 单个 unit 的最后 100 行
journalctl -n 100 --no-pager # 打印后退出——接管道必备 --no-pager 比看上去重要:不加它,journalctl 会打开 less,你的脚本、管道或 ssh 一行式命令就会卡在等按键上。任何输出要进管道的命令都应该带上它。
怎么像 tail -f 一样实时跟踪日志?
-f 就是 journalctl 版的 tail -f——新条目一产生就流式输出:
journalctl -f # 所有日志,实时
journalctl -u sshd -f # 只看 SSH 守护进程,实时
journalctl -u ollama -f -n 50 # 实时,但先带上最后 50 行 这条命令适合挂在第二个终端里,同时在第一个终端重启服务:一个窗格跑 systemctl restart nginx,另一个窗格跑 journalctl -u nginx -f,崩溃原因通常几秒内自己冒出来。每次有容器或服务闹脾气,我在自己的 homelab 上跑的就是这套循环。
怎么查看某个服务的日志?
-u 按 systemd unit 过滤:
journalctl -u nginx # 单个 unit,全部历史
journalctl -u nginx -u redis # 同时看多个 unit
journalctl _SYSTEMD_UNIT=nginx.service # 精确匹配的替代写法 unit 可能会拉起一些保存了关键输出的辅助 unit——一个挂掉的 Web 应用,真正的错误有时记在另一个 unit 名下。如果 -u <service> 查不到东西而服务明明在跑,先找到真实的 unit 名:
systemctl list-units --type=service | grep -i <guess> 同样的 -u 模式也适用于 timer(名字用 systemctl list-timers 查)和用户级服务——凡是跑在 systemd --user 下的东西,加上 --user:
journalctl --user -u pipewire -n 50 怎么按时间过滤日志?
--since 和 --until 接受时间戳,也接受相当宽松的相对表达:
journalctl --since "1 hour ago"
journalctl --since "2026-09-01 09:00" --until "2026-09-01 12:00"
journalctl --since today
journalctl --since yesterday --until now -u cron 把时间窗口和 unit 一组合,一行命令就是事故分诊:“API 在 09:00 到挂掉之间记了什么?“对单台机器来说,这比任何日志聚合系统都快。
怎么只看错误(或警告)?
-p 按优先级过滤,使用 syslog 的严重级别名称:
journalctl -p err -b # 只看错误,本次开机以来
journalctl -p warning..alert -u nginx # 一个严重级别区间 优先级从高到低:emerg、alert、crit、err、warning、notice、info、debug。当一台机器”行为怪异”时,journalctl -p err -b --since today 是最快的清醒测试——它直接回答”到底有没有东西在失败?“,滤掉日常 info 行的噪音。
怎么查看上一次开机的日志?
启动时崩溃的服务,其日志行产生于当前这次开机之前,而 journalctl 默认只显示当前这次。-b 用来选开机记录:
journalctl -b # 仅本次开机
journalctl -b -1 # 上一次开机
journalctl -b -1 -u sshd # 上次 SSH 为什么挂了
journalctl --list-boots # 已存储开机的索引 对于”坏了、重启了、然后错误看不见了”的场景,这是最值得记住的一个 flag——错误还在那儿,就在上一次开机里。
速查表:值得背下来的 flag
| 目标 | 命令 |
|---|---|
| 实时跟踪一个服务 | journalctl -u <svc> -f |
| 最后 100 行 | journalctl -n 100 |
| 最近一小时起 | journalctl --since "1 hour ago" |
| 本次开机的错误 | journalctl -p err -b |
| 上一次开机 | journalctl -b -1 |
| journal 占用的磁盘空间 | journalctl --disk-usage |
| 机器可读输出 | journalctl -o json-pretty |
| 仅内核消息 | journalctl -k |
怎么防止 journal 塞满磁盘?
先看它花了多少空间,再设上限:
journalctl --disk-usage
sudo journalctl --vacuum-size=500M # 只保留最新的 500 MB
sudo journalctl --vacuum-time=30d # 只保留最近 30 天 要让上限永久生效,把 SystemMaxUse=500M 写进 /etc/systemd/journald.conf 的 [Journal] 段,然后 sudo systemctl restart systemd-journald。有了大小上限加上面的开机过滤,journal 就重新变回工具,而不是缓慢的磁盘泄漏。
journalctl、dmesg、/var/log——先查哪个?
journalctl——应用和服务的行为。systemd 管理的一切都在这里,有索引、可过滤。默认第一站。journalctl -k/dmesg——内核和硬件:OOM kill、USB 重置、磁盘错误。进程死得不明不白时,先来这里找 OOM killer,再怪应用。/var/log/<app>/——只留给自己做文件日志的应用(nginx 访问日志、PostgreSQL)。即便如此,启动错误通常还是会进 journal。
同一套流程也适用于本地 AI 服务——ollama serve 的 unit 卡住时,journalctl -u ollama -n 100 会立刻显示模型加载失败,详见 Ollama vs LM Studio 对比。
速查表到此为止:-u 选 unit,-f 跟踪,-n 限行数,--since 管时间,-p 管级别,-b 管开机。六个 flag,几乎能回答一台 Linux 机器抛给你的所有日志问题。
— mrsaynothing
Get the next one by email
One email per post. No spam, no algorithms.
what is this?Ollama vs LM Studio:本地大模型工具怎么选?
喜欢这些文章?我的本职工作就是这样的工程。 雇用我