【Linux运维极简教程】10-日志管理与故障排查

10 - 日志管理与故障排查

一、Linux 日志体系

1.1 日志服务

现代 Linux 使用 systemd-journaldrsyslog 两套日志系统:

服务 特点 日志位置
journald 二进制格式,结构化,易查询 /run/log/journal/
rsyslog 文本格式,可定制,传统方案 /var/log/

1.2 常见日志文件

日志文件 内容
/var/log/messages 系统通用日志(CentOS)
/var/log/syslog 系统通用日志(Ubuntu)
/var/log/secure 安全日志:登录、sudo(CentOS)
/var/log/auth.log 安全日志(Ubuntu)
/var/log/cron cron 定时任务日志
/var/log/maillog 邮件服务日志
/var/log/dmesg 内核启动日志
/var/log/boot.log 系统启动日志
/var/log/yum.log yum 安装日志(CentOS)
/var/log/dpkg.log dpkg 安装日志(Ubuntu)

1.3 应用日志常见位置

复制代码
/var/log/nginx/          # Nginx 日志
/var/log/mysql/          # MySQL 日志
/var/log/httpd/          # Apache 日志
/var/lib/docker/         # Docker 日志
/opt/app/logs/           # 自定义应用日志

二、journalctl - 日志查询利器

2.1 基本查询

bash 复制代码
# 查看所有日志
journalctl

# 查看最新日志并持续追踪(类似 tail -f)
journalctl -f

# 查看最后 N 条
journalctl -n 50

# 查看今天的日志
journalctl --since today

# 指定时间范围
journalctl --since "2024-01-15 09:00:00" --until "2024-01-15 12:00:00"
journalctl --since "1 hour ago"
journalctl --since "30 min ago"

2.2 按服务/单元查询

bash 复制代码
# 查看指定服务的日志
journalctl -u nginx
journalctl -u sshd -f                # 实时追踪
journalctl -u nginx --since today

# 查看多个服务
journalctl -u nginx -u php-fpm

2.3 按优先级查询

bash 复制代码
# 日志优先级(0-7)
# 0 emerg   紧急
# 1 alert   警报
# 2 crit    严重
# 3 err     错误
# 4 warning 警告
# 5 notice  通知
# 6 info    信息
# 7 debug   调试

# 只看错误及以上
journalctl -p err

# 查看指定级别
journalctl -p warning

# 查看某级别及以上
journalctl -p warning..err

2.4 按其他条件查询

bash 复制代码
# 按进程 PID
journalctl _PID=1234

# 按用户
journalctl _UID=1000

# 按可执行文件
journalctl /usr/bin/nginx

# 按设备
journalctl /dev/sda

# 只显示内核日志
journalctl -k

# 只显示本次启动的日志
journalctl -b

# 查看上一次启动的日志
journalctl -b -1

# 以 JSON 格式输出
journalctl -o json
journalctl -o json-pretty

2.5 journal 持久化

默认 journal 日志存储在 /run/log/journal/,重启后会丢失。配置持久化:

bash 复制代码
# 创建持久化目录
mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal

# 重启 journald
systemctl restart systemd-journald

# 配置日志大小限制
# 编辑 /etc/systemd/journald.conf
[Journal]
Storage=persistent           # 持久化存储
SystemMaxUse=500M            # 最大使用 500MB
SystemKeepFree=1G            # 至少保留 1GB 空闲
MaxRetentionSec=30day        # 保留 30 天

# 查看磁盘使用
journalctl --disk-usage

# 清理日志
journalctl --vacuum-time=7d       # 清理 7 天前的
journalctl --vacuum-size=200M     # 只保留 200MB

三、rsyslog 配置

3.1 配置文件

bash 复制代码
# 主配置文件
/etc/rsyslog.conf

# 子配置目录
/etc/rsyslog.d/*.conf

3.2 配置语法

复制代码
# 格式:设施.级别    动作
# 设施:auth, authpriv, cron, daemon, kern, mail, user, local0-7, *
# 级别:debug, info, notice, warning, err, crit, alert, emerg, *
# 动作:文件路径,@主机(IP),|程序

# 示例
*.info;mail.none;authpriv.none;cron.none   /var/log/messages
authpriv.*                                  /var/log/secure
mail.*                                      /var/log/maillog
cron.*                                      /var/log/cron
*.emerg                                     :omusrmsg:*
local7.*                                    /var/log/boot.log

3.3 自定义应用日志

bash 复制代码
# 让应用日志通过 rsyslog 管理
cat > /etc/rsyslog.d/myapp.conf << 'EOF'
if $programname == 'myapp' then /var/log/myapp/app.log
& stop
EOF

systemctl restart rsyslog

# 应用中使用 logger 命令写入日志
logger -t myapp "Application started"
logger -t myapp -p local0.info "Info message"
logger -t myapp -p local0.err "Error message"

四、日志分析技巧

4.1 grep 搜索

bash 复制代码
# 搜索关键词
grep "error" /var/log/messages

# 忽略大小写
grep -i "error" /var/log/messages

# 显示行号
grep -n "error" /var/log/messages

# 显示上下文
grep -C 3 "error" /var/log/messages       # 前后各 3 行
grep -B 2 "error" /var/log/messages       # 前 2 行
grep -A 5 "error" /var/log/messages       # 后 5 行

# 统计错误数量
grep -c "error" /var/log/messages

# 多关键词
grep -E "error|warning|fail" /var/log/messages

4.2 统计与分析

bash 复制代码
# 统计 IP 访问次数(Nginx 日志)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 统计 HTTP 状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# 统计访问最多的 URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# 统计每小时的访问量
awk '{print $4}' /var/log/nginx/access.log | cut -c 14-15 | sort | uniq -c

# 找出 404 错误
grep ' 404 ' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn

# 找出响应慢的请求
awk '($NF > 3){print $7, $NF}' /var/log/nginx/access.log | sort -k2 -rn | head -10

4.3 多文件搜索

bash 复制代码
# 在多个日志文件中搜索
grep "error" /var/log/nginx/*.log

# 递归搜索
grep -rn "config" /etc/

# 只在特定时间范围搜索
awk '/2024-01-15 10:/{p=1} /2024-01-15 11:/{p=0} p' /var/log/messages

五、logrotate 日志轮转

logrotate 自动切割、压缩和清理日志文件。

5.1 配置文件

bash 复制代码
# 主配置
/etc/logrotate.conf

# 子配置目录
/etc/logrotate.d/

5.2 配置示例

bash 复制代码
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily              # 每天轮转
    rotate 30          # 保留 30 份
    missingok          # 日志不存在不报错
    compress           # 压缩旧日志
    delaycompress      # 延迟压缩(最近一份不压缩)
    notifempty         # 空文件不轮转
    create 0640 nginx adm   # 创建新日志文件的权限
    sharedscripts      # 多个日志匹配时脚本只执行一次
    postrotate         # 轮转后执行的脚本
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 $(cat /var/run/nginx.pid)
        fi
    endscript
}

5.3 常用参数

参数 说明
daily/weekly/monthly 轮转周期
rotate N 保留 N 份旧日志
size 100M 超过 100MB 时轮转
compress 压缩旧日志
delaycompress 延迟一轮再压缩
missingok 日志不存在不报错
notifempty 空日志不轮转
copytruncate 复制后截断原文件(不重启服务)
create 创建新的日志文件
postrotate/endscript 轮转后执行脚本

5.4 手动执行与调试

bash 复制代码
# 手动执行所有轮转
logrotate /etc/logrotate.conf

# 调试模式(只显示会做什么,不实际执行)
logrotate -d /etc/logrotate.d/nginx

# 强制执行
logrotate -f /etc/logrotate.d/nginx

# 查看轮转状态
cat /var/lib/logrotate/logrotate.status

六、故障排查方法论

6.1 排查思路

复制代码
发现问题 → 定位范围 → 查看日志 → 分析原因 → 解决问题 → 记录归档

6.2 常见故障排查

服务无法启动
bash 复制代码
# 1. 查看服务状态(会显示错误信息)
systemctl status nginx

# 2. 查看详细日志
journalctl -u nginx --since "10 min ago"

# 3. 检查配置文件语法
nginx -t
httpd -t
sshd -t

# 4. 查看应用自身日志
tail -50 /var/log/nginx/error.log

# 5. 检查端口冲突
ss -tlnp | grep :80
系统变慢
bash 复制代码
# 1. 查看系统负载
uptime
top

# 2. 查看高 CPU 进程
ps -eo pid,user,%cpu,%mem,command --sort=-%cpu | head -10

# 3. 查看高内存进程
ps -eo pid,user,%cpu,%mem,command --sort=-%mem | head -10

# 4. 查看 IO 等待
iostat -x 1 3
iotop                  # 查看哪个进程在做 IO

# 5. 检查磁盘空间
df -h
SSH 无法登录
bash 复制代码
# 在服务器上排查(需要通过其他方式登录,如控制台)

# 1. 检查 sshd 服务
systemctl status sshd

# 2. 查看安全日志
# CentOS
tail -50 /var/log/secure
# Ubuntu
tail -50 /var/log/auth.log

# 3. 检查 sshd 配置
sshd -t                  # 语法检查
grep -E "^(PermitRootLogin|PasswordAuthentication|AllowUsers)" /etc/ssh/sshd_config

# 4. 检查防火墙
firewall-cmd --list-all
iptables -L -n | grep 22

# 5. 检查 PAM 限制
cat /etc/security/limits.conf | grep -v "^#"
网络不通
bash 复制代码
# 1. 检查网卡状态
ip link show
ip addr show

# 2. 检查路由
ip route show
ping <gateway>
ping 8.8.8.8

# 3. 检查 DNS
dig example.com
cat /etc/resolv.conf

# 4. 抓包分析
tcpdump -i eth0 -nn host <target_ip>
磁盘空间满
bash 复制代码
# 1. 查看分区使用
df -h

# 2. 找大文件
du -sh /* 2>/dev/null | sort -rh | head -10
find / -type f -size +1G 2>/dev/null

# 3. 检查 inode 是否耗尽
df -i
find / -type f | wc -l

# 4. 检查已删除但未释放的文件
lsof +L1 | grep deleted
# 或
lsof | grep deleted

# 5. 清理常见日志
journalctl --vacuum-size=100M
find /var/log -name "*.gz" -mtime +30 -delete

七、实战场景

场景一:分析 SSH 暴力破解

bash 复制代码
#!/bin/bash
# 分析 SSH 登录失败记录,统计攻击 IP

echo "===== SSH 登录失败统计 ====="
echo ""

# CentOS
grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20

# Ubuntu
# grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20

echo ""
echo "===== 成功登录记录 ====="
grep "Accepted password" /var/log/secure | tail -10

echo ""
echo "===== 最近登录用户 ====="
last -20

场景二:一键系统诊断脚本

bash 复制代码
#!/bin/bash
# system_diagnose.sh - 快速诊断系统状态

echo "=============================="
echo "  系统诊断报告 - $(date)"
echo "=============================="
echo ""

echo "--- 系统信息 ---"
echo "主机名: $(hostname)"
echo "系统: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
echo "内核: $(uname -r)"
echo "运行时间: $(uptime -p)"
echo ""

echo "--- 负载情况 ---"
uptime
echo ""

echo "--- CPU 使用 TOP5 ---"
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head -6
echo ""

echo "--- 内存使用 ---"
free -h
echo ""
echo "内存使用 TOP5:"
ps -eo pid,user,%cpu,%mem,comm --sort=-%mem | head -6
echo ""

echo "--- 磁盘空间 ---"
df -h | grep -v tmpfs
echo ""

echo "--- 磁盘 IO ---"
iostat -x 1 1 2>/dev/null | tail -n +4 || echo "iostat 未安装"
echo ""

echo "--- 网络连接数 ---"
echo "TCP 连接总数: $(ss -tn | tail -n +2 | wc -l)"
echo "TIME_WAIT: $(ss -tn state TIME-WAIT | wc -l)"
echo "ESTABLISHED: $(ss -tn state ESTABLISHED | wc -l)"
echo ""

echo "--- 监听端口 ---"
ss -tlnp | head -20
echo ""

echo "--- 最近错误日志 ---"
journalctl -p err --since "1 hour ago" --no-pager | tail -20
echo ""

echo "=============================="
echo "  诊断完成"
echo "=============================="

八、小结

本篇介绍了 Linux 日志体系(journald + rsyslog)、journalctl 查询技巧、日志分析命令、logrotate 日志轮转以及系统故障排查方法论。日志是排查问题的金矿,熟练使用日志查询和分析工具是运维工程师的核心能力。


上一篇09 - 定时任务与自动化运维

下一篇11 - 防火墙与安全加固

相关推荐
聚焦前沿1 小时前
2026服务器热管理阀门选型白皮书
运维·服务器
明亮 Blog1 小时前
Wi-Fi 6/7的物联网“芯”机遇:高带宽低延时如何重塑智慧工厂的AGV物流革命
服务器·网络·数据库
杜子不疼.1 小时前
N5105小主机只装NAS太浪费?我把它改成了All-in-One家庭服务器
运维·服务器
笑锝没心没肺2 小时前
提升CPU平均使用率(自用)
linux·运维
宵时待雨2 小时前
linux笔记归纳9:进程间通信
linux·服务器·笔记
Zhang~Ling2 小时前
深入学习Linux: 命令行参数与环境变量详解
linux·服务器
会飞的小新2 小时前
《深入理解 DDR Memory Margin》系列之第四章 从 Bit Error 到 ECC——服务器为什么能够发现内存错误?
运维·服务器
Shadow(⊙o⊙)2 小时前
日志与线程池
linux·c++·算法
无锡银洲自动化2 小时前
烟气监测取样频繁堵管?防堵取样器解决工业运维通病
运维·产品运营