15_日志排查:5 分钟定位 Linux 系统故障

日志排查:5 分钟定位 Linux 系统故障

Linux 系统的 “日志” 就像 “黑匣子”—— 当服务崩溃、硬件报错、网络中断时,所有关键信息都藏在日志里。很多新手排查故障时会 “四处乱找”,浪费大量时间;其实掌握journalctldmesg等工具,结合日志分析技巧,5 分钟内就能定位大部分问题。今天这篇文章,带你从 “日志工具使用” 到 “实战故障定位”,再到 “多服务器日志收集”,形成完整的日志排查能力。

一、基础工具:搞定日志 “查看” 与 “轮转”

排查故障前,先掌握两个核心工具:journalctl(查看 systemd 日志,覆盖系统与服务)和logrotate(日志轮转,避免日志撑爆磁盘),这是日志排查的 “基本功”。

1. journalctl:systemd 日志的 “全能查看器”

大部分现代 Linux(Ubuntu 16.04+、CentOS 7+)用 systemd 管理服务,对应的日志统一存在journalctl中,涵盖系统启动、服务运行、内核报错等信息,无需记住多个日志文件路径。

(1)核心用法:3 个高频场景

需求 命令 关键参数解读
查看某服务日志(如 Nginx) journalctl -u nginx -u:指定服务单元(unit),只显示该服务的日志
实时追踪日志(类似 tail -f) journalctl -u nginx -f -f:实时跟随日志输出,新日志会自动刷新
按时间筛选日志(近 1 小时) journalctl -u nginx --since "1 hour ago" --since/--until:按时间范围筛选,支持 “10min ago”“2024-10-25 14:00” 等格式

(2)进阶筛选:快速定位关键日志

排查故障时,常需要按 “错误级别”“关键字” 筛选,减少无效信息:

\# 1. 只看Nginx的错误日志(优先级err及以上:err/warning/crit/alert/emerg)

journalctl -u nginx -p err  # -p:指定优先级(priority)

\# 2. 搜索包含“failed”关键词的Nginx日志(大小写不敏感)

journalctl -u nginx -i | grep "failed"  # -i:grep忽略大小写

\# 3. 查看某时间段内的内核日志(内核日志用\_-kernel.service单元)

journalctl -u \_-kernel.service --since "2024-10-25 14:00" --until "2024-10-25 14:30"

(3)避坑:journalctl 日志不持久化

默认情况下,journalctl日志只保存在内存中,重启后丢失。若需持久化(长期保存日志),需手动配置:

\# 1. 创建日志存储目录

sudo mkdir -p /var/log/journal

\# 2. 重启systemd-journald服务

sudo systemctl restart systemd-journald

\# 3. 验证:重启后 journalctl -u nginx 仍能看到之前的日志

2. logrotate:日志轮转的 “自动管家”

应用日志(如 Nginx、MySQL)会持续增长,若不处理,可能几小时就占满磁盘(比如 10GB 的访问日志)。logrotate能自动 “切割日志、压缩归档、删除旧日志”,是日志管理的必备工具。

(1)核心配置:理解 logrotate 规则

logrotate的配置文件分两类:

  • 全局配置:/etc/logrotate.conf(定义默认规则,如默认保留 4 份轮转日志);

  • 应用配置:/etc/logrotate.d/目录下(针对单个应用,如/etc/logrotate.d/nginx,优先级高于全局配置)。

(2)实战:配置 Nginx 日志轮转

以 Nginx 日志(/var/log/nginx/access.logerror.log)为例,编写轮转配置:

\# 1. 创建Nginx的logrotate配置文件

sudo vim /etc/logrotate.d/nginx

\# 2. 写入以下配置(逐行解读)

/var/log/nginx/\*.log {  # 匹配Nginx的所有.log文件

    daily               # 轮转周期:每天1次(可选weekly/monthly)

    rotate 7            # 保留7份归档日志(超过7天的自动删除)

    compress            # 归档日志用gzip压缩(节省磁盘空间)

    delaycompress       # 延迟压缩:只压缩前一天的日志(避免正在写的日志被压缩)

    missingok           # 若日志文件不存在,不报错(避免手动删除日志后轮转失败)

    notifempty          # 若日志为空,不执行轮转

    create 0640 www-data www-data  # 新建日志文件的权限、所有者、所属组(匹配Nginx运行用户)

    sharedscripts       # 所有日志文件轮转后,只执行一次postrotate脚本

    postrotate          # 轮转后执行的脚本(Nginx需重新打开日志文件,否则继续写旧日志)

        if \[ -f /var/run/nginx.pid ]; then

            kill -USR1 \`cat /var/run/nginx.pid\`  # 发送USR1信号,Nginx重新打开日志

        fi

    endscript

}

(3)验证:测试 logrotate 配置是否生效

配置后,无需等待 “每天轮转”,可手动触发测试:

\# 1. 测试配置(无报错说明配置正确)

sudo logrotate -d /etc/logrotate.d/nginx  # -d:dry run,只模拟,不实际执行

\# 2. 强制执行轮转(实际切割日志)

sudo logrotate -f /etc/logrotate.d/nginx  # -f:force,强制轮转

\# 3. 验证结果:查看Nginx日志目录,会生成access.log.1.gz(归档压缩的旧日志)和新的access.log

ls -l /var/log/nginx/

二、实战排障:5 分钟定位两类高频故障

掌握工具后,结合 “系统服务故障” 和 “硬件故障” 两个场景,演示如何快速定位问题。

实战 1:Nginx 服务崩溃 —— 从日志找原因

场景:执行sudo systemctl start nginx,提示 “Job for nginx.service failed because the control process exited with error code.”,需 5 分钟内定位崩溃原因。

步骤 1:1 分钟看 systemd 日志(初步定位)

先用journalctl查看 Nginx 服务的错误日志,获取关键线索:

journalctl -u nginx -p err --no-pager  # --no-pager:不分页,直接显示所有错误日志

常见错误日志与原因

  • 日志 1:nginx: [emerg] bind() to ``0.0.0.0:80`` failed (98: Address already in use)

    → 原因:80 端口被其他进程占用(如 Apache);

  • 日志 2:nginx: [emerg] invalid parameter "worker_processes" in /etc/nginx/nginx.conf:2

    → 原因:Nginx 配置文件语法错误(第 2 行worker_processes参数无效);

  • 日志 3:nginx: [emerg] open() "/var/log/nginx/error.log" failed (13: Permission denied)

    → 原因:Nginx 运行用户(www-data)无日志文件写入权限。

步骤 2:2 分钟查 Nginx 专属日志(精准定位)

systemd 日志可能不够详细,需查看 Nginx 自己的错误日志(路径在/etc/nginx/nginx.conf中定义,默认/var/log/nginx/error.log):

\# 查看错误日志的最后20行(最新错误)

tail -n 20 /var/log/nginx/error.log

举例:若日志显示2024/10/25 14:30:00 [crit] 1234#0: *5 open() "/var/www/html/index.html" failed (2: No such file or directory),说明 Nginx 配置的网站根目录/var/www/html下缺少index.html文件,导致访问时崩溃。

步骤 3:2 分钟验证并解决问题

  • 若为端口占用:用lsof -i :80找到占用进程(如PID=567apache2),sudo kill -9 567关闭后,重启 Nginx;

  • 若为配置错误:用nginx -t检查配置语法(sudo nginx -t),根据提示修改/etc/nginx/nginx.conf,再重启;

  • 若为权限问题:执行sudo chown -R www-data:www-data /var/log/nginx/,赋予 Nginx 用户权限。

验证sudo systemctl start nginxsudo systemctl status nginx显示 “active (running)”,故障解决。

实战 2:硬件报错 —— 用 dmesg 解读内核日志

场景:服务器频繁卡顿,偶尔蓝屏,怀疑硬件故障(如磁盘坏道、内存错误),需通过内核日志排查。

步骤 1:1 分钟查看 dmesg 实时内核日志

dmesg用于查看内核日志(包括硬件初始化、驱动报错、磁盘 / 内存故障),默认输出所有日志,需按 “错误关键词” 筛选:

\# 查看包含“error”“warn”“fail”关键词的内核日志(忽略大小写)

dmesg | grep -iE "error|warn|fail"

步骤 2:3 分钟解读常见硬件故障日志

(1)磁盘坏道(最常见)

日志特征:包含 “bad sector”“I/O error”“sdX”(X 为磁盘编号,如 sda):

\[1234.567890] sd 0:0:0:0: \[sda] Add. Sense: Unrecovered read error - auto reallocate failed

\[1234.567900] sd 0:0:0:0: \[sda] CDB: Read(10): 28 00 00 12 34 56 00 00 08 00

\[1234.567910] blk\_update\_request: I/O error, dev sda, sector 123456 op 0x0:(READ) flags 0x80700 phys\_seg 1 prio class 0

→ 解读:sda磁盘的 123456 扇区有坏道,读取失败;

→ 解决:立即备份/dev/sda上的数据,用fsck /dev/sda1修复坏道,若频繁报错,更换磁盘。

(2)内存错误

日志特征:包含 “memory error”“EDAC”“MC0”(内存控制器):

\[7890.123456] EDAC MC0: UE error count (addr 0x12345678): 1

\[7890.123460] EDAC MC0: CE error count: 0

\[7890.123465] EDAC MC0: UE error (synd 0x12345678, addr 0x12345678, layer Memory, gran 64B)

→ 解读:内存地址0x12345678出现不可纠正错误(UE),可能导致程序崩溃或蓝屏;

→ 解决:用memtest86+工具检测内存(需重启从 U 盘启动),确认故障内存插槽后,更换内存条。

步骤 3:1 分钟保存 dmesg 日志(便于后续分析)

dmesg 日志在重启后会清空,需保存到文件:

\# 保存当前dmesg日志到文件

dmesg > /var/log/dmesg\_20241025.log

\# 后续可通过该文件分析历史硬件报错

cat /var/log/dmesg\_20241025.log | grep "sda"

三、进阶方案:多服务器远程日志收集

当管理 10 台、100 台 Linux 服务器时,逐台登录看日志效率极低 —— 需搭建 “远程日志收集系统”,让所有服务器的日志统一发送到 “日志服务器”,实现 “集中查看、快速检索”。

这里推荐用rsyslog(Linux 默认预装,配置简单)搭建基础远程日志系统,适合中小规模服务器(大规模可用 ELK 栈,后续进阶)。

1. 步骤 1:配置 “日志服务器”(接收日志)

假设日志服务器 IP 为192.168.1.100,负责接收其他服务器的日志:

\# 1. 编辑rsyslog配置文件

sudo vim /etc/rsyslog.conf

\# 2. 开启UDP/TCP接收模块(取消以下两行注释,任选一种协议,UDP简单,TCP可靠)

module(load="imudp")  # 加载UDP接收模块

input(type="imudp" port="514")  # 监听514端口(rsyslog默认端口)

\# module(load="imtcp")  # 加载TCP接收模块

\# input(type="imtcp" port="514")

\# 3. 配置日志存储规则(所有远程日志保存到/var/log/remote/目录,按服务器IP分类)

\$template RemoteLog,"/var/log/remote/%FROMHOST-IP%/%PROGRAMNAME%.log"  # 模板:按IP和程序名存日志

\*.\* ?RemoteLog  # 所有级别(\*.\*)的日志,按模板存储

\# 4. 重启rsyslog服务

sudo systemctl restart rsyslog

\# 5. 开放防火墙端口(允许514端口的UDP/TCP流量)

sudo ufw allow 514/udp  # Ubuntu

\# sudo firewall-cmd --add-port=514/udp --permanent && sudo firewall-cmd --reload  # CentOS

2. 步骤 2:配置 “客户端服务器”(发送日志)

假设客户端服务器 IP 为192.168.1.101,需将日志发送到192.168.1.100

\# 1. 编辑rsyslog配置文件

sudo vim /etc/rsyslog.conf

\# 2. 添加日志发送规则(所有日志通过UDP发送到日志服务器)

\*.\* @192.168.1.100:514  # @表示UDP,@@表示TCP,端口514

\# 若只发送Nginx日志,可更精准:

\# :programname,isequal,"nginx" @192.168.1.100:514

\# 3. 重启rsyslog服务

sudo systemctl restart rsyslog

3. 步骤 3:验证远程日志收集

\# 1. 在客户端服务器生成测试日志(触发日志发送)

logger "test remote log from 192.168.1.101"  # logger命令用于生成自定义日志

\# 2. 在日志服务器查看是否收到日志

ls -l /var/log/remote/192.168.1.101/  # 会看到logger.log文件

cat /var/log/remote/192.168.1.101/logger.log  # 能看到测试日志内容,说明配置成功

进阶:大规模场景推荐 ELK 栈

若服务器超过 50 台,rsyslog的检索能力不足,可搭建 ELK 栈(Elasticsearch+Logstash+Kibana):

  • Logstash:收集日志并格式化;

  • Elasticsearch:存储日志并支持全文检索;

  • Kibana:可视化日志(图表、仪表盘),支持按 IP、时间、关键词快速筛选。

四、避坑指南:3 个日志排查常见误区

1. 误区 1:只看 systemd 日志,忽略应用专属日志

表现:Nginx 启动失败,只看journalctl -u nginx,没看/var/log/nginx/error.log,错过配置文件语法错误的详细提示。

正确做法:systemd 日志看 “服务状态”,应用专属日志看 “具体错误细节”,两者结合才能快速定位。

2. 误区 2:logrotate 配置后不测试,日志撑爆磁盘

表现:配置 Nginx 日志轮转后,未手动测试,实际轮转时因 “权限不足” 失败,导致access.log涨到 100GB 占满磁盘。

正确做法:配置后必执行sudo logrotate -d /etc/logrotate.d/nginx(模拟测试)和sudo logrotate -f ...(强制执行),验证轮转是否正常生成归档日志。

3. 误区 3:远程日志收集不开放防火墙端口

表现:客户端配置好 rsyslog,日志服务器却收不到日志,排查半天发现防火墙未开放 514 端口。

正确做法:配置远程日志时,先在日志服务器执行sudo netstat -tuln | grep 514,确认 rsyslog 已监听 514 端口,再开放防火墙端口(UDP/TCP)。

总结:5 分钟日志排查核心流程

  1. 服务故障

    1 分钟journalctl -u 服务名 -p err看系统日志 → 2 分钟tail -n 20 应用日志路径看细节 → 2 分钟验证解决;

  2. 硬件故障

    1 分钟dmesg | grep -i error找报错 → 3 分钟解读日志定位硬件(磁盘 / 内存) → 1 分钟保存日志并处理;

  3. 多服务器

    rsyslog搭建远程收集,中小规模够用;大规模用 ELK 栈,实现可视化检索。

掌握这套流程,你就能从 “日志小白” 变成 “故障排查高手”,大部分 Linux 故障都能在 5 分钟内定位,不再因 “找不到原因” 而焦虑。

posted @ 2025-10-12 18:56  S&L·chuck  阅读(8)  评论(0)    收藏  举报