路线图

日志与排查思路

星辉 2026-07-02 阅读 6 min 1,180 字 路线图
日志与排查思路 封面

Linux 运维基础 · 第十五章 目标:建立系统化排查思维,知道出问题后从哪开始、往哪查


1. 概述#

这是本教程的终章。前面十四章讲了工具和操作,这一章把它们串起来:出现故障后,你的排查路径是什么?

核心就一句话:日志确认识现象 → 进程确认服务状态 → 网络确认连通性 → 磁盘确认空间 → 内核确认硬件。把这条链路刻在脑子里,大部分故障都能自己搞定。


2. 日志体系全景#

2.1 /var/log 目录速查#

bash
ls -la /var/log/
日志文件内容何时看
/var/log/syslog系统主日志(Debian/Ubuntu任何不知来源的问题
/var/log/messages系统主日志(RHEL/Rocky/Alma同上
/var/log/auth.log认证日志:登录/sudo/SSH(Debian/UbuntuSSH 连不上、权限异常
/var/log/secure认证日志(RHEL/Rocky/Alma,对应 auth.log)同上
/var/log/kern.log内核日志(Debian 系;RHEL 走 messages/journald)硬件错误、驱动问题
/var/log/dpkg.log包管理日志(Debian/Ubuntu)装了/卸了什么包
/var/log/yum.log包管理日志(旧 CentOS/yum;RHEL 8+ 已改用 dnf,日志在 /var/log/dnf.logdnf.rpm.log同上
/var/log/nginx/Nginx 访问和错误日志网站状态码异常
/var/log/apt/APT 详细日志包管理故障详解
/var/log/boot.log启动过程日志服务开机自启失败
/var/log/faillog登录失败记录faillog 命令查看

两套日志系统并存,别只盯一边 现代发行版上 journald(二进制,journalctl 看)rsyslog(纯文本,/var/log/* 通常同时在跑:journald 先统一收集所有日志,再转发给 rsyslog 落成 /var/log/syslog(或 messages)。

  • journald 的优势:结构化、能按服务(-u)/优先级(-p)/时间(--since)/启动次数(-b)过滤。
  • 纯文本日志的优势grep/awk 顺手、远程集中收集、第三方工具兼容。
  • :有些精简容器/镜像只装了 journald/var/log/syslog 根本不存在—— 这时别去 tail /var/log/syslog,直接 journalctl。反过来,某些应用只写自己的 /var/log/xxx/,不进 journald,得去对应目录翻。
  • journald 默认可能不持久化(重启即丢),排障前确认已开持久化(见第 13 章 4.4)。

2.2 日志轮替(logrotate)#

bash
# 日志文件不会无限增长,logrotate 负责旋转
cat /etc/logrotate.conf                           # 全局配置
ls /etc/logrotate.d/                              # 各服务的旋转策略

# 手动触发
logrotate -f /etc/logrotate.conf
logrotate -f /etc/logrotate.d/nginx

# 典型配置
# /var/log/myapp/*.log {
#     daily                 # 每天旋转
#     rotate 7              # 保留 7 份
#     compress              # 压缩旧日志
#     missingok             # 文件不存在不报错
#     notifempty            # 空文件不旋转
#     copytruncate          # 复制后截断(不中断服务)
# }

3. dmesg — 内核日志#

bash
dmesg -T                       # 【首选】-T 把"开机秒数"转成可读的墙上时间,否则时间戳没法和日志对齐
dmesg -T | tail -50            # 最近 50 条
dmesg -T | grep -i error       # 找错误
dmesg -T | grep -i fail        # 找失败

# 默认不带 -T 时,时间戳形如 [12345.678],是【开机后经过的秒数】,不是日期——排查时务必加 -T

# 按级别过滤
dmesg -T --level=err           # 只看错误
dmesg -T --level=err,warn      # 错误 + 警告

# 实时查看
dmesg -Tw                      # -w 持续跟踪(类似 tail -f),配 -T 更易读

# 注意:部分系统限制非 root 读 dmesg(内核参数 kernel.dmesg_restrict=1),加 sudo

什么情况用 dmesg#

  • 磁盘 I/O 错误
  • 内存错误(ECC 故障)
  • 驱动加载失败
  • OOM(Out of Memory)事件
  • 硬件热插拔事件

4. journalctl 进阶#

bash
# 按时间:只看今天的
journalctl --since today

# 全局搜索关键词
journalctl --grep="OOM"
journalctl --grep="killed process"

# 只看内核日志
journalctl -k
journalctl -k --since today

# 只看错误级别
journalctl -p err --since today

# 看某个服务的详细日志
journalctl -u nginx -n 100 --no-pager -l

# 看从某个时间点开始的
journalctl --since "2026-07-01 09:00:00" --until "2026-07-01 10:00:00"

# 导出日志
journalctl --since today > /tmp/today_logs.txt

5. 排查思路总纲#

5.1 四步排查法#

text
第 1 步:日志 (Logs)
第 2 步:进程 (Process)
第 3 步:网络 (Network)
第 4 步:磁盘 (Disk)
第 5 步:内核/硬件 (Kernel/Hardware)

从外到内、从现象到根因。

5.2 每一步查什么#

步骤查什么命令
日志确认故障现象和时间点systemctl status / journalctl -u / tail / grep
进程服务在不在跑?CPU/内存正常吗?ps aux / top / systemctl status
网络端口在监听吗?能连上吗?ss -tlnp / nc / curl / ping
磁盘空间满了吗?inode 满了吗?df -h / df -i / du -sh
内核/硬件硬件报错?内存故障?dmesg / journalctl -k / free -h

6. 实战场景#

实战 1:服务启动失败#

用户反馈:"网站打不开了"

bash
# 第 1 步:日志 — 确认现象
systemctl status nginx --no-pager -l
# Active: failed (Result: exit-code)
# nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
# ^ 一看就明白:80 端口被占了

# 第 2 步:进程 — 确认谁占的端口
ss -tlnp | grep :80
# LISTEN  0  128  0.0.0.0:80  0.0.0.0:*  users:(("nginx",pid=5678,fd=6))
# 老的 nginx 进程没死透

# 解决
kill 5678                       # 杀掉旧进程
systemctl start nginx           # 重启
systemctl status nginx          # 确认 OK

# 如果日志没有明显报错,继续深入:
journalctl -u nginx -n 100 --no-pager
# 找启动前后的日志

# 还不行?手动跑看报错
sudo -u www-data nginx -t       # 测试配置
sudo nginx                      # 前台启动看直接报错

实战 2:磁盘写满#

监控告警:磁盘使用率 > 95%

bash
# 第 1 步:确认告警
df -h
# /dev/sda1       50G  48G    0  100% /     ← 真满了

# 第 2 步:找大户
du -sh /* 2>/dev/null | sort -rh | head -10
# 24G    /var
# 12G    /home
# 8.5G   /usr

# 第 3 步:深入 /var
du -h --max-depth=1 /var/ | sort -rh | head
# 22G    /var/log
du -h --max-depth=1 /var/log/ | sort -rh | head
# 18G    /var/log/journal         ← journald 日志太大了

# 第 4 步:清理
du -sh /var/log/journal/
journalctl --disk-usage
journalctl --vacuum-size=500M
df -h /
# 恢复了

# 如果 du 加起来不大,df 却满了 → 幽灵文件(进程占着已删除的文件)
lsof +L1 | awk '{print $1, $7}' | sort -nrk2 | head
# 找到后重启对应进程

# 如果 df -h 显示还有空间却报 No space left on device → inode 耗尽
df -i                            # 看 IUse%,到 100% 就是 inode 满了(小文件太多)
# 定位:for d in /var/*; do echo "$(find "$d" 2>/dev/null|wc -l) $d"; done | sort -rn | head

实战 3:SSH 连不上#

场景:ssh user@server 卡住或提示 Connection refused

bash
# 事前检查(如果能通过云控制台/串口登录)

# 第 1 步:防火墙
# 检查是不是防火墙挡住了
iptables -L -n                  # 或 firewall-cmd --list-all
# 确认 22 端口是否开放

# 第 2 步:sshd 在跑吗
systemctl status sshd           # 或 ssh
# Active: inactive (dead)       ← 没跑!

# 第 3 步:看认证日志
tail -50 /var/log/auth.log      # 或 /var/log/secure
# 有无登录失败记录?
# 有无 "Connection closed" 的记录?

# 第 4 步:端口在监听吗
ss -tlnp | grep :22
# 没输出 → sshd 没起来

# 启动
systemctl start sshd
systemctl enable sshd           # 设为开机自启

# 第 5 步:从外部测
# 在本地机器上:
ssh -v user@server              # -v 看详细连接过程
nc -zv server_ip 22             # 端口是否可达

实战 4:OOM(内存溢出)#

进程莫名挂了,日志里没有异常

bash
# 第 1 步:看内核日志(加 -T 才知道是【什么时候】被杀的)
dmesg -T | grep -i "killed process"
# [Wed Jul  1 02:14:07 2026] Out of memory: Killed process 8901 (java) total-vm:4194304kB
# 关键信息:oom-kill 会打印是谁触发的、被杀进程的 RSS、以及 total_vm,据此定位内存大户

# 第 2 步:看 journald
journalctl --grep="killed process" --since today

# 第 3 步:确认当前内存
free -h
# Mem:          7.8G       7.5G       156M       1.2G       100M       1.0G
# 可用内存极低

# 第 4 步:找吃内存大户
ps aux --sort=-%mem | head -10
# 或 top 按 M 排序

# 临时缓解:加 swap
dd if=/dev/zero of=/swapfile bs=1G count=4
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

# 长期修复:增加物理内存 / 优化应用内存使用 / 加内存限制

7. 排障工具速查表#

故障类型第一步命令关键工具
服务起不来systemctl status <svc> + journalctl -u <svc> -n 50journalctl, systemctl
磁盘满df -h + du -sh /* | sort -rhdf, du, lsof
内存高free -h + ps aux --sort=-%memfree, ps, top, dmesg
CPU 高toptop -H -p <pid>top, ps
网络不通pingnc -zvcurl -vping, nc, curl, ss, traceroute
DNS 异常dig +short <domain> + cat /etc/resolv.confdig, nslookup
SSH 连不上nc -zv host 22 + 控制台看 auth.lognc, journalctl, ss
服务响应慢curl -o /dev/null -w 看各阶段耗时curl, strace, tcpdump

8. 运维应急流程图#

text
用户报故障
【1. 日志】— 确认现象和时间点
    ├── systemctl status <服务>
    ├── journalctl -u <服务> -n 50
    ├── tail -100 /var/log/<服务>/error.log
    └── dmesg | tail
【2. 进程】— 确认服务状态
    ├── 在运行吗?→ systemctl status / ps aux
    ├── CPU/内存正常吗?→ top / free -h
    └── 重启有效吗?→ systemctl restart
【3. 网络】— 确认连通性
    ├── 端口监听?→ ss -tlnp | grep <port>
    ├── 能连上?→ nc -zv <host> <port>
    ├── DNS 解析?→ dig +short <domain>
    └── 防火墙通?→ iptables -L / firewall-cmd --list-all
【4. 磁盘】— 确认存储
    ├── 空间满?→ df -h / df -i
    ├── 谁占的多?→ du -sh /* | sort -rh
    └── 幽灵文件?→ lsof | grep deleted
【5. 内核/硬件】— 底层排查
    ├── 内核报错?→ dmesg | grep -i error
    ├── OOM?→ dmesg | grep -i killed
    └── 硬件故障?→ dmesg -T | tail
解决 / 升级求助

9. 好习惯#

  1. 操作前先备份:改配置前 cp config.conf config.conf.bak.$(date +%Y%m%d)
  2. 一步一步改:别同时改多个配置项,改完一项测一项
  3. 记录操作:在 tmux 里操作,自动留下完整记录,方便回看和交接
  4. 先查后改:不确认根因不动手,尤其是 rm -rfkill -9
  5. 永远有回滚方案:改之前想好"怎么改回去"
  6. 结构化排障:不要东一榔头西一棒子,按四步法走

10. 小结#

知识点一句话记忆
日志体系Debian 系 syslog/auth.log,RHEL 系 messages/secure;服务日志 journalctl -u
journald vs rsyslog二者并存,journctl 看结构化、/var/log/* 供 grep;容器里可能只有 journald
四步排查日志→进程→网络→磁盘→内核,从现象到根因
服务失败systemctl status + journalctl -u -n 50 三步以内定位
磁盘满df -h 看块空间、df -i 看 inode,du -sh /* 找大户,lsof | grep deleted 找幽灵
SSH 不通nc -zv host 22 测端口,控制台看 auth.log/secure
OOMdmesg -T | grep killed 确认,free -h 看现状,加 swap 应急
dmesg一律加 -T,否则时间戳是开机秒数不是日期

上一章:十四、Shell 脚本

全教程目录