系统日志与排障

日志是事后排查的核心依据,记录系统运行中发生的事件(正常、警告、错误、崩溃)。日志来源分两类:内核环形缓冲区用户态日志服务

一、内核日志: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 单元的日志(如 sshnginx
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/syslogless /var/log/messagesgrep 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 -hdu -sh *lsof | grep deleted
内存不足内存状态 + OOM 日志free -hdmesg | grep oom
网络不通网卡状态 + 内核日志ip admesg | grep -i ethernet

核心思路

  1. 先看时间线——问题发生在何时?journalctl --since "10 minutes ago" 锁定窗口。
  2. 再看优先级——journalctl -p err 只关注错误,过滤噪音。
  3. 三看关联单元——journalctl -u 服务名 精确定位到具体组件。
  4. 终看内核态——若用户态日志无异常,回查 dmesg 确认内核是否已拦截操作。

笔记结语

日志排障的核心认知:

  1. 日志分两源 —— 内核环形缓冲区(dmesg)和用户态日志服务(journalctl/var/log/ 文本文件)。
  2. journalctl 是 systemd 的日志接口,非 systemd 系统则直接查看 /var/log/ 下的文件。
  3. 过滤器比全量阅读重要 —— 按单元(-u)、按优先级(-p)、按时间(--since)精确定位。
  4. lsof/proc/[PID]/fd/ 的封装,排查文件句柄残留时比直接读目录更便捷。
  5. 读日志不是背格式 —— 知道去哪看、用什么过滤,比记得住所有错误码重要得多。