4、systemd日志系统:journalctl基础用法、日志优先级过滤、按时间范围查询、实时跟踪日志
日志这东西,平时没人看,一出事全盯着它。我见过太多运维同事,服务器挂了先翻 /var/log/messages,翻半天啥也没找到。其实从 CentOS 7 开始,systemd 就把日志系统彻底重写了。你想想看,一个 journalctl 命令就能搞定所有事,何必再去翻那些零散的文件?
今天咱们就把 journalctl 吃透。说白了,它就是 systemd 日志的瑞士军刀。
4.1 为什么是 journald?
传统 syslog 有个毛病:日志格式不统一,不同程序写出来的东西长得完全不一样。而且日志文件散落在 /var/log 下面,查个东西要 grep 好几个文件。
journald 不一样。它把日志收拢到二进制文件里,统一管理。好处很明显:
- 结构化存储:每条日志都带时间戳、优先级、进程ID、代码行号等元数据
- 索引查询:按服务名、优先级、时间范围查,秒级响应
- 自动轮转:默认只占 10% 的磁盘空间,超了自动清理
4.2 journalctl 基础用法
先来几个最常用的操作。你不需要记太多参数,记住这几个就够了。
4.2.1 查看所有日志
journalctl
这条命令会输出所有日志,从系统启动到现在。内容非常多,一般配合 less 翻页看。按 q 退出。
4.2.2 查看指定服务的日志
journalctl -u nginx.service
journalctl -u sshd.service
我在项目中遇到过一个问题:Nginx 突然 502,查了半天发现是 upstream 挂了。用 journalctl -u nginx.service -f 实时看日志,瞬间定位到错误。
4.2.3 查看内核日志
journalctl -k
内核日志很重要。硬件报错、驱动崩溃、OOM killer 杀进程,这些信息都在这里。我曾经靠 journalctl -k | grep -i error 找到一块坏掉的内存条。
4.2.4 查看本次启动的日志
journalctl -b
系统重启后,想看这次启动过程中有没有报错?加个 -b 就行。想看上一次启动的日志?用 journalctl -b -1。
| 参数 | 作用 | 示例 |
|---|---|---|
-u |
按服务名过滤 | journalctl -u docker.service |
-k |
只看内核日志 | journalctl -k |
-b |
本次启动日志 | journalctl -b -1 |
-f |
实时跟踪 | journalctl -f |
-n |
显示最近 N 条 | journalctl -n 50 |
--no-pager |
不分页输出 | journalctl --no-pager |
4.3 日志优先级过滤
日志有 8 个优先级,从 0(紧急)到 7(调试)。你想想看,生产环境里如果连 debug 日志都看,眼睛会瞎的。
| 优先级 | 数值 | 含义 | 典型场景 |
|---|---|---|---|
| emerg | 0 | 系统不可用 | 内核崩溃 |
| alert | 1 | 必须立即处理 | 磁盘损坏 |
| crit | 2 | 严重错误 | 服务挂掉 |
| err | 3 | 错误 | 配置错误 |
| warning | 4 | 警告 | 磁盘空间不足 |
| notice | 5 | 正常但重要 | 服务启动 |
| info | 6 | 普通信息 | 请求日志 |
| debug | 7 | 调试信息 | 开发用 |
4.3.1 按优先级过滤
# 只看错误及以上级别
journalctl -p err
# 只看警告及以上级别
journalctl -p warning
# 只看紧急级别
journalctl -p emerg
这里有个坑:-p err 会包含 err、crit、alert、emerg 四个级别。它其实是「从 err 往上」的意思。如果你只想看 err 本身,需要用 -p err..err。
journalctl -p err 查问题,发现日志很少,以为系统很健康。后来才发现,有些关键错误被记录为 crit 级别,被我漏掉了。建议排查问题时先用 -p warning,再逐步收紧。
4.3.2 组合过滤
# 查看 nginx 服务的错误日志
journalctl -u nginx.service -p err
# 查看内核的警告日志
journalctl -k -p warning
4.4 按时间范围查询
这是 journalctl 最强大的功能之一。传统 syslog 查某个时间段的日志,你得先知道日志文件什么时候轮转的,然后一个个 grep。journalctl 直接按时间查,精确到微秒。
4.4.1 相对时间
# 最近 5 分钟
journalctl --since "5 min ago"
# 最近 1 小时
journalctl --since "1 hour ago"
# 最近 2 天
journalctl --since "2 days ago"
4.4.2 绝对时间
# 从某个时间点开始
journalctl --since "2024-01-15 10:00:00"
# 到某个时间点结束
journalctl --until "2024-01-15 12:00:00"
# 指定时间段
journalctl --since "2024-01-15 10:00:00" --until "2024-01-15 12:00:00"
4.4.3 实战案例
我记得有一次,线上服务在凌晨 3 点准时挂掉。我用了这条命令:
journalctl -u app.service --since "03:00" --until "03:05" -p err
5 秒就定位到问题:cron 在 3 点触发了一个日志清理脚本,把应用日志目录删了。嗯,这就是典型的「定时炸弹」。
--since "yesterday" 昨天全天--since "today" 今天全天--since "1 hour ago" --until "30 min ago" 半小时前到一小时前
4.5 实时跟踪日志
调试问题的时候,实时看日志是刚需。journalctl 的 -f 参数和 tail -f 类似,但功能更强。
4.5.1 基本实时跟踪
journalctl -f
所有新产生的日志会实时打印到终端。按 Ctrl+C 退出。
4.5.2 跟踪指定服务
journalctl -u nginx.service -f
这个我天天用。上线新版本的时候,开一个终端窗口跑这个命令,另一个窗口做部署。一旦报错,立刻就能看到。
4.5.3 跟踪时带过滤
# 实时看 nginx 的错误日志
journalctl -u nginx.service -f -p err
# 实时看内核日志
journalctl -k -f
4.5.4 跟踪最近 N 条
journalctl -u nginx.service -n 50 -f
先显示最近的 50 条日志,然后开始实时跟踪。这个组合非常实用,能让你看到上下文。
窗口1:
journalctl -u app.service -f -p err窗口2:
journalctl -u app.service --since "1 hour ago" | grep -i error窗口3:
htop 看系统资源三个窗口一对照,问题基本就清楚了。
4.6 知识体系总览
下面这张图把 journalctl 的核心用法串起来了。你照着这个思路去用,基本不会迷路。
4.7 实用技巧与避坑
4.7.1 日志持久化
默认情况下,journald 的日志存在内存里,重启就没了。如果你需要持久化,要改配置:
mkdir -p /var/log/journal
systemctl restart systemd-journald
嗯,这一步很多人会忘。我建议生产环境一定要做,否则重启后查不到历史日志,排查问题会很被动。
4.7.2 查看日志占用的磁盘空间
journalctl --disk-usage
这个命令会告诉你日志文件占了多少空间。如果发现日志太大,可以手动清理:
# 保留最近 3 天
journalctl --vacuum-time=3d
# 保留最近 500M
journalctl --vacuum-size=500M
4.7.3 输出格式控制
# JSON 格式输出,方便程序解析
journalctl -o json
# 只输出消息内容,不输出元数据
journalctl -o cat
# 详细格式,包含所有字段
journalctl -o verbose
我在写自动化脚本时,经常用 -o json 配合 jq 解析,非常方便。
--no-pager,否则脚本会卡住。
4.8 本章小结
journalctl 是 systemd 日志系统的核心工具。你只要记住几个关键点:
- 用
-u指定服务,用-p过滤优先级 - 用
--since和--until锁定时间范围 - 用
-f实时跟踪,配合-n看上下文 - 生产环境一定要做日志持久化
这些基础操作熟练了,后面讲高级查询和日志分析的时候,你就能跟上节奏了。