10 - 日志管理与故障排查
一、Linux 日志体系
1.1 日志服务
现代 Linux 使用 systemd-journald 和 rsyslog 两套日志系统:
| 服务 | 特点 | 日志位置 |
|---|---|---|
| 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 - 防火墙与安全加固