系统日志与排障
日志是事后排查的核心依据,记录系统运行中发生的事件(正常、警告、错误、崩溃)。日志来源分两类:内核环形缓冲区和用户态日志服务。
一、内核日志:dmesg
内核在启动和运行时将硬件识别、驱动加载、内存分配、中断分配等信息写入环形缓冲区。
dmesg # 全部内核日志
dmesg | tail -20 # 最新 20 条
dmesg | grep -i error # 过滤错误
dmesg | grep -i usb # 仅查看 USB 设备事件
dmesg -T # 带时间戳(可读时间格式)典型排障场景:
- 硬盘识别失败、分区表损坏 →
dmesg | grep -i sda - 网卡驱动未加载 →
dmesg | grep -i ethernet - OOM(内存不足)触发 →
dmesg | grep -i oom
dmesg 是内核环形缓冲区的直接读取接口,不依赖任何用户态服务。
二、用户态日志:journalctl(systemd)
若 PID 1 为 systemd,journalctl 是统一日志管理工具,收集内核消息、服务日志、用户会话事件。日志以结构化二进制格式存储,支持按时间、单元、优先级过滤。
核心用法:
| 命令 | 说明 |
|---|---|
journalctl -f | 实时跟踪最新日志(类似 tail -f) |
journalctl -u 服务名 | 仅查看特定 systemd 单元的日志(如 ssh、nginx) |
journalctl -k | 仅内核日志(等同于 dmesg) |
journalctl -b | 本次启动以来的日志 |
journalctl -b -1 | 上一次启动的日志(排障启动失败时用) |
journalctl --since "2026-07-12 10:00:00" | 按时间过滤 |
journalctl -p err | 仅显示错误级别及以上的日志(优先级:emerg, alert, crit, err) |
journalctl -o json | 以 JSON 格式输出(便于脚本解析) |
查看日志占用:journalctl --disk-usage。清理日志:journalctl --vacuum-size=200M(仅保留最近 200MB 日志)。
三、传统文本日志(非 systemd)
不使用 systemd 的系统(如 Alpine OpenRC、Gentoo OpenRC、Void runit)将日志写入 /var/log/ 下的文本文件:
/var/log/messages # 系统通用日志(RHEL 系)
/var/log/syslog # 系统日志(Debian 系)
/var/log/auth.log # 认证与授权日志(登录、sudo)
/var/log/kern.log # 内核日志
查看方式:tail -f /var/log/syslog、less /var/log/messages、grep ssh /var/log/auth.log。
四、查看进程打开的文件描述符:lsof(排障辅助)
当怀疑文件被进程锁住,或磁盘空间被已删除文件占用时,用 lsof 排查进程持有的文件句柄。
lsof # 列出所有进程打开的文件
lsof /path/to/file # 查看哪个进程在使用该文件
lsof -p 1234 # 查看特定进程打开的文件
lsof -i :80 # 查看哪个进程占用了 80 端口
lsof | grep deleted # 查找已被删除但进程仍持有的文件(占磁盘空间)lsof 读取 /proc/[PID]/fd/ 目录,是上述 /proc 知识的直接应用。
五、排障方法论
日志是排障的原料,关键在于知道从哪看、怎么过滤。
| 问题类型 | 查看对象 | 命令 |
|---|---|---|
| 硬件识别失败 | 内核日志 | dmesg | grep -i error |
| 服务无法启动 | 服务日志 | journalctl -u 服务名 -f(或 /var/log/syslog) |
| 登录失败(SSH) | 认证日志 | journalctl -u sshd(或 tail -f /var/log/auth.log) |
| 磁盘满 | 磁盘占用 + 文件句柄 | df -h、du -sh *、lsof | grep deleted |
| 内存不足 | 内存状态 + OOM 日志 | free -h、dmesg | grep oom |
| 网络不通 | 网卡状态 + 内核日志 | ip a、dmesg | grep -i ethernet |
核心思路:
- 先看时间线——问题发生在何时?
journalctl --since "10 minutes ago"锁定窗口。 - 再看优先级——
journalctl -p err只关注错误,过滤噪音。 - 三看关联单元——
journalctl -u 服务名精确定位到具体组件。 - 终看内核态——若用户态日志无异常,回查
dmesg确认内核是否已拦截操作。
笔记结语
日志排障的核心认知:
- 日志分两源 —— 内核环形缓冲区(
dmesg)和用户态日志服务(journalctl或/var/log/文本文件)。 journalctl是 systemd 的日志接口,非 systemd 系统则直接查看/var/log/下的文件。- 过滤器比全量阅读重要 —— 按单元(
-u)、按优先级(-p)、按时间(--since)精确定位。 lsof是/proc/[PID]/fd/的封装,排查文件句柄残留时比直接读目录更便捷。- 读日志不是背格式 —— 知道去哪看、用什么过滤,比记得住所有错误码重要得多。