2、日志收集基础:journalctl命令入门
日志这东西,平时没人搭理它,一出问题就成了救命稻草。我在系统运维这行干了十来年,见过太多「要是早点看日志就好了」的案例。今天咱们就从最基础的 journalctl 开始聊。
2.1 为什么是 journalctl?
以前 Linux 的日志都散落在 /var/log/ 下面,messages、syslog、secure……找起来得翻好几个文件。systemd 出来之后,统一用 journald 管理日志。说白了,journalctl 就是它的查看工具。
我个人习惯,接手一台新服务器,第一件事就是跑一下 journalctl --version,确认版本。嗯,这里要注意,不同发行版的 journalctl 功能略有差异,但核心命令都一样。
2.2 入门三板斧
先来几个最常用的命令,你试试看:
# 查看所有日志(默认从旧到新)
journalctl
# 查看最新日志(类似 tail -f)
journalctl -f
# 查看本次启动以来的日志
journalctl -b
为什么要加 -b? 因为 journald 默认保留所有历史启动的日志。不加 -b 的话,你可能会看到几个月前的记录。我在项目中遇到过,有同事排查问题,翻到去年的日志,差点被误导。
核心要点: journalctl 不加参数,输出的是全部日志。生产环境慎用,数据量可能非常大。
2.3 查看实时日志
实时日志,说白了就是动态追踪。你部署完服务,想看看有没有报错,用这个最方便。
# 实时滚动输出
journalctl -f
# 只看最近 50 行,然后开始实时追踪
journalctl -n 50 -f
我调试 Nginx 配置的时候,经常开两个终端:一个改配置,一个跑 journalctl -u nginx -f。改完立马能看到效果,效率很高。
小技巧: 按 Ctrl+C 退出实时模式。如果日志刷得太快,可以加 --since "1 min ago" 缩小范围。
2.4 按时间过滤日志
时间过滤,这是排查问题的基本功。你想想看,用户说「昨天下午 3 点网站挂了」,你总不能从头翻到尾吧?
# 查看某个时间点之后的日志
journalctl --since "2024-01-15 14:00:00"
# 查看某个时间段内的日志
journalctl --since "2024-01-15 14:00:00" --until "2024-01-15 15:00:00"
# 更人性化的写法
journalctl --since "2 hours ago"
journalctl --since "yesterday" --until "today"
journalctl --since "2024-01-15" --until "2024-01-16"
我曾经排查过一个诡异的内存泄漏问题。客户说「每周三下午服务器就卡」。我用 --since "wednesday" --until "thursday" 过滤,发现是定时任务触发的。要是没有时间过滤,这问题得查三天。
注意: 时间格式要写对。journalctl 支持 "2024-01-15 14:00:00" 这种标准格式,也支持 "yesterday" "today" "now" 这些关键词。但别写 "2024/01/15",它会报错。
2.5 按服务过滤日志
系统里跑着几十个服务,你只关心某一个。这时候就用 -u 参数。
# 查看某个服务的日志
journalctl -u nginx.service
# 查看多个服务的日志
journalctl -u nginx.service -u mysql.service
# 结合时间和服务过滤
journalctl -u sshd.service --since "1 hour ago"
这里有个坑,我踩过好几次。服务名要不要加 .service 后缀?其实都可以。journalctl 会自动补全。但如果你写错了名字,它不会报错,只会返回空结果。所以,我建议你养成习惯,先确认服务名:
# 查看所有可用的服务单元
systemctl list-units --type=service
# 或者直接查
systemctl status nginx
实战组合拳: 排查问题时,我通常这样用:journalctl -u nginx.service -f -n 100 --since "30 min ago"。这条命令的意思是:只看 Nginx 的日志,显示最近 100 行,并且实时追踪,时间范围是最近半小时。一步到位。
2.6 其他实用过滤
| 过滤方式 | 命令示例 | 说明 |
|---|---|---|
| 按优先级 | journalctl -p err |
只显示错误级别及以上的日志 |
| 按进程ID | journalctl _PID=1234 |
查看某个进程的日志 |
| 按用户 | journalctl _UID=1000 |
查看某个用户的日志 |
| 按内核 | journalctl -k |
只看内核日志 |
优先级这块,我多说一句。journalctl 的优先级从 emerg 到 debug 共 7 级。生产环境我一般用 -p err,只看错误。但调试的时候,-p debug 能帮你看到很多细节。
我的习惯: 日常巡检用 journalctl -p warning -b --since "1 day ago"。这样既能发现潜在问题,又不会被海量信息淹没。
2.7 输出格式控制
默认的输出格式是分页的,跟 less 命令一样。你可以用方向键翻页,按 q 退出。但有时候我们需要更灵活的格式:
# 输出为 JSON 格式(方便程序解析)
journalctl -o json
# 输出为简短格式(一行一条)
journalctl -o short
# 输出为详细格式(包含所有字段)
journalctl -o verbose
# 不进行分页,直接输出
journalctl --no-pager
我个人最喜欢 -o short-full,它会在每行前面显示完整的时间戳,方便复制到 Excel 里分析。
2.8 日志持久化
默认情况下,journald 的日志存在内存里,重启就没了。如果你希望日志持久化,需要做个小配置:
# 创建日志存储目录
sudo mkdir -p /var/log/journal
# 重启 journald 服务
sudo systemctl restart systemd-journald
配置完之后,日志会保存在 /var/log/journal/ 目录下。即使服务器重启,历史日志也不会丢失。我在生产环境都是这么干的,不然重启后查不到日志,那可就抓瞎了。
重要提醒: 持久化日志会占用磁盘空间。建议设置日志大小限制,在 /etc/systemd/journald.conf 中配置 SystemMaxUse=500M,避免日志把磁盘撑爆。
2.9 本章小结
journalctl 这东西,说简单也简单,说复杂也复杂。但作为入门,你只要记住这几点:
- 实时查看:
journalctl -f - 按时间过滤:
--since和--until - 按服务过滤:
-u 服务名 - 组合使用: 把上面几个参数串起来用
下一章,咱们会深入聊 journalctl 的高级用法,包括如何自定义字段过滤、如何导出日志、如何做日志审计。到时候你会发现,journalctl 远比你想象的强大。