【Linux运维极简教程】10-日志管理与故障排查
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 基本查询
# 查看所有日志journalctl# 查看最新日志并持续追踪(类似 tail -f)journalctl-f# 查看最后 N 条journalctl-n50# 查看今天的日志journalctl--sincetoday# 指定时间范围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 按服务/单元查询
# 查看指定服务的日志journalctl-unginx journalctl-usshd-f# 实时追踪journalctl-unginx--sincetoday# 查看多个服务journalctl-unginx-uphp-fpm2.3 按优先级查询
# 日志优先级(0-7)# 0 emerg 紧急# 1 alert 警报# 2 crit 严重# 3 err 错误# 4 warning 警告# 5 notice 通知# 6 info 信息# 7 debug 调试# 只看错误及以上journalctl-perr# 查看指定级别journalctl-pwarning# 查看某级别及以上journalctl-pwarning..err2.4 按其他条件查询
# 按进程 PIDjournalctl_PID=1234# 按用户journalctl_UID=1000# 按可执行文件journalctl /usr/bin/nginx# 按设备journalctl /dev/sda# 只显示内核日志journalctl-k# 只显示本次启动的日志journalctl-b# 查看上一次启动的日志journalctl-b-1# 以 JSON 格式输出journalctl-ojson journalctl-ojson-pretty2.5 journal 持久化
默认 journal 日志存储在/run/log/journal/,重启后会丢失。配置持久化:
# 创建持久化目录mkdir-p/var/log/journal systemd-tmpfiles--create--prefix/var/log/journal# 重启 journaldsystemctl restart systemd-journald# 配置日志大小限制# 编辑 /etc/systemd/journald.conf[Journal]Storage=persistent# 持久化存储SystemMaxUse=500M# 最大使用 500MBSystemKeepFree=1G# 至少保留 1GB 空闲MaxRetentionSec=30day# 保留 30 天# 查看磁盘使用journalctl --disk-usage# 清理日志journalctl --vacuum-time=7d# 清理 7 天前的journalctl --vacuum-size=200M# 只保留 200MB三、rsyslog 配置
3.1 配置文件
# 主配置文件/etc/rsyslog.conf# 子配置目录/etc/rsyslog.d/*.conf3.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.log3.3 自定义应用日志
# 让应用日志通过 rsyslog 管理cat>/etc/rsyslog.d/myapp.conf<<'EOF' if $programname == 'myapp' then /var/log/myapp/app.log & stop EOFsystemctl restart rsyslog# 应用中使用 logger 命令写入日志logger-tmyapp"Application started"logger-tmyapp-plocal0.info"Info message"logger-tmyapp-plocal0.err"Error message"四、日志分析技巧
4.1 grep 搜索
# 搜索关键词grep"error"/var/log/messages# 忽略大小写grep-i"error"/var/log/messages# 显示行号grep-n"error"/var/log/messages# 显示上下文grep-C3"error"/var/log/messages# 前后各 3 行grep-B2"error"/var/log/messages# 前 2 行grep-A5"error"/var/log/messages# 后 5 行# 统计错误数量grep-c"error"/var/log/messages# 多关键词grep-E"error|warning|fail"/var/log/messages4.2 统计与分析
# 统计 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# 统计访问最多的 URLawk'{print $7}'/var/log/nginx/access.log|sort|uniq-c|sort-rn|head-20# 统计每小时的访问量awk'{print $4}'/var/log/nginx/access.log|cut-c14-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-104.3 多文件搜索
# 在多个日志文件中搜索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 配置文件
# 主配置/etc/logrotate.conf# 子配置目录/etc/logrotate.d/5.2 配置示例
# /etc/logrotate.d/nginx/var/log/nginx/*.log{daily# 每天轮转rotate30# 保留 30 份missingok# 日志不存在不报错compress# 压缩旧日志delaycompress# 延迟压缩(最近一份不压缩)notifempty# 空文件不轮转create 0640 nginx adm# 创建新日志文件的权限sharedscripts# 多个日志匹配时脚本只执行一次postrotate# 轮转后执行的脚本if[-f/var/run/nginx.pid];thenkill-USR1$(cat/var/run/nginx.pid)fiendscript}5.3 常用参数
| 参数 | 说明 |
|---|---|
| daily/weekly/monthly | 轮转周期 |
| rotate N | 保留 N 份旧日志 |
| size 100M | 超过 100MB 时轮转 |
| compress | 压缩旧日志 |
| delaycompress | 延迟一轮再压缩 |
| missingok | 日志不存在不报错 |
| notifempty | 空日志不轮转 |
| copytruncate | 复制后截断原文件(不重启服务) |
| create | 创建新的日志文件 |
| postrotate/endscript | 轮转后执行脚本 |
5.4 手动执行与调试
# 手动执行所有轮转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 常见故障排查
服务无法启动
# 1. 查看服务状态(会显示错误信息)systemctl status nginx# 2. 查看详细日志journalctl-unginx--since"10 min ago"# 3. 检查配置文件语法nginx-thttpd-tsshd-t# 4. 查看应用自身日志tail-50/var/log/nginx/error.log# 5. 检查端口冲突ss-tlnp|grep:80系统变慢
# 1. 查看系统负载uptimetop# 2. 查看高 CPU 进程ps-eopid,user,%cpu,%mem,command--sort=-%cpu|head-10# 3. 查看高内存进程ps-eopid,user,%cpu,%mem,command--sort=-%mem|head-10# 4. 查看 IO 等待iostat-x13iotop# 查看哪个进程在做 IO# 5. 检查磁盘空间df-hSSH 无法登录
# 在服务器上排查(需要通过其他方式登录,如控制台)# 1. 检查 sshd 服务systemctl status sshd# 2. 查看安全日志# CentOStail-50/var/log/secure# Ubuntutail-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|grep22# 5. 检查 PAM 限制cat/etc/security/limits.conf|grep-v"^#"网络不通
# 1. 检查网卡状态iplinkshowipaddr show# 2. 检查路由iproute showping<gateway>ping8.8.8.8# 3. 检查 DNSdigexample.comcat/etc/resolv.conf# 4. 抓包分析tcpdump-ieth0-nnhost<target_ip>磁盘空间满
# 1. 查看分区使用df-h# 2. 找大文件du-sh/*2>/dev/null|sort-rh|head-10find/-typef-size+1G2>/dev/null# 3. 检查 inode 是否耗尽df-ifind/-typef|wc-l# 4. 检查已删除但未释放的文件lsof+L1|grepdeleted# 或lsof|grepdeleted# 5. 清理常见日志journalctl --vacuum-size=100Mfind/var/log-name"*.gz"-mtime+30-delete七、实战场景
场景一:分析 SSH 暴力破解
#!/bin/bash# 分析 SSH 登录失败记录,统计攻击 IPecho"===== SSH 登录失败统计 ====="echo""# CentOSgrep"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 -20echo""echo"===== 成功登录记录 ====="grep"Accepted password"/var/log/secure|tail-10echo""echo"===== 最近登录用户 ====="last-20场景二:一键系统诊断脚本
#!/bin/bash# system_diagnose.sh - 快速诊断系统状态echo"=============================="echo" 系统诊断报告 -$(date)"echo"=============================="echo""echo"--- 系统信息 ---"echo"主机名:$(hostname)"echo"系统:$(cat/etc/os-release|grepPRETTY_NAME|cut-d'"'-f2)"echo"内核:$(uname-r)"echo"运行时间:$(uptime-p)"echo""echo"--- 负载情况 ---"uptimeecho""echo"--- CPU 使用 TOP5 ---"ps-eopid,user,%cpu,%mem,comm--sort=-%cpu|head-6echo""echo"--- 内存使用 ---"free-hecho""echo"内存使用 TOP5:"ps-eopid,user,%cpu,%mem,comm--sort=-%mem|head-6echo""echo"--- 磁盘空间 ---"df-h|grep-vtmpfsecho""echo"--- 磁盘 IO ---"iostat-x112>/dev/null|tail-n+4||echo"iostat 未安装"echo""echo"--- 网络连接数 ---"echo"TCP 连接总数:$(ss-tn|tail-n+2|wc-l)"echo"TIME_WAIT:$(ss-tnstate TIME-WAIT|wc-l)"echo"ESTABLISHED:$(ss-tnstate ESTABLISHED|wc-l)"echo""echo"--- 监听端口 ---"ss-tlnp|head-20echo""echo"--- 最近错误日志 ---"journalctl-perr--since"1 hour ago"--no-pager|tail-20echo""echo"=============================="echo" 诊断完成"echo"=============================="八、小结
本篇介绍了 Linux 日志体系(journald + rsyslog)、journalctl 查询技巧、日志分析命令、logrotate 日志轮转以及系统故障排查方法论。日志是排查问题的金矿,熟练使用日志查询和分析工具是运维工程师的核心能力。
上一篇:09 - 定时任务与自动化运维
下一篇:11 - 防火墙与安全加固
