引言
日志是运维工程师排查问题的第一手资料。当服务器出现异常时,系统日志、应用日志、安全日志中往往隐藏着问题的答案。然而,很多工程师面对海量的日志数据不知从何看起,要么遗漏关键信息,要么被无关数据淹没。
本文面向初中级运维工程师,系统讲解Linux系统日志的分析方法和排查技巧。文章不追求覆盖所有日志类型,而是从实战出发,讲解最重要的日志来源、最常用的分析命令、最典型的故障场景。读完本文后,读者应该能够:理解Linux主要日志文件的作用和格式、熟练使用grep、awk、sed等工具进行日志分析、快速定位常见的系统异常问题、建立日志分析的基本思路。
假设读者具备基本的Linux操作能力,熟悉常用的命令如ls、cat、head、tail等。文中示例基于CentOS/RHEL 7/8系统,其他发行版可能略有差异。
一、Linux日志基础
1.1 日志系统架构
Linux的日志系统主要由三部分组成:syslog守护进程、rsyslog服务、systemd的journal。
传统的CentOS 6及更早版本使用syslog作为日志守护进程。CentOS 7及更新版本使用rsyslog,它是syslog的增强版,支持更丰富的过滤规则和输出格式。Ubuntu 16.04及更新版本、SUSE系列发行版也使用rsyslog。
最新的主流Linux发行版(CentOS 8、Ubuntu 20.04+、Debian 10+)引入了systemd-journald作为日志收集器。journald提供结构化日志、索引搜索、二进制日志等特性,比传统syslog更强大。rsyslog和journald可以协同工作,也可以单独运行。
理解这个架构有助于理解日志的存储位置和格式。
1.2 重要日志文件一览
Linux系统中最重要的日志文件位于/var/log目录下:
ls -la /var/log/
主要日志文件的作用:
/var/log/messages:系统主日志,记录内核、应用程序的常规信息。这个文件是最常用的故障排查日志,几乎所有系统问题都可以从这里找到线索。在CentOS/RHEL系统中,messages包含系统级的info、warning、error信息。
/var/log/syslog:系统日志,Ubuntu/Debian系统的主日志。与messages类似,但包含的来源可能更广。
/var/log/dmesg:内核环缓冲区日志,记录系统启动时的硬件检测信息和内核模块加载信息。dmesg对于排查硬件驱动问题和启动故障特别有用。
/var/log/secure:安全日志,记录认证和授权相关的事件。包括SSH登录、PAM认证、sudo使用、cron任务等信息。这个日志是排查入侵和安全问题的第一手资料。
/var/log/audit/audit.log:审计日志,记录SELinux、审计规则匹配等信息。只有安装了audit服务才会生成。
/var/log/yum.log:yum包管理器日志,记录软件包的安装、升级、删除操作。
/var/log/cron:crontab任务执行日志,记录定时任务的运行情况。
/var/log/maillog:邮件服务器日志,记录邮件发送、接收、投递情况。
**/var/log/httpd/或/var/log/nginx/**:Web服务器日志。access_log记录访问请求,error_log记录错误信息。
**/var/log/mysql/或/var/log/mariadb/**:数据库日志。记录查询、错误、慢查询等信息。
/var/log/boot.log:系统启动日志,记录启动过程的服务初始化情况。
1.3 journalctl基础用法
systemd-journald提供了强大的日志查询工具journalctl。
查看所有日志:
journalctl
默认使用less分页显示,按q退出,j/k上下滚动。
查看最新日志并实时跟踪:
journalctl -f
类似tail -f,持续显示新产生的日志。
查看指定时间范围的日志:
# 查看最近10分钟的日志 journalctl --since "10 minutes ago" # 查看指定时间点的日志 journalctl --since "2026-05-13 1000" # 查看时间范围 journalctl --since "2026-05-13 1000" --until "2026-05-13 1100" # 昨天的日志 journalctl --since yesterday --until today
查看指定服务的日志:
journalctl -u nginx.service journalctl -u sshd.service journalctl -u kubelet -u containerd # 多个服务
查看内核日志:
journalctl -k # 等价于 dmesg
1.4 日志级别
Linux系统日志使用标准的日志级别:
| 级别 | 名称 | 说明 |
|---|---|---|
| 0 | emerg | 系统不可用 |
| 1 | alert | 必须立即处理 |
| 2 | crit | 严重错误 |
| 3 | error | 错误 |
| 4 | warning | 警告 |
| 5 | notice | 正常但重要 |
| 6 | info | 信息 |
| 7 | debug | 调试信息 |
排查问题时,重点关注error、warning、crit、alert、emerg级别的日志。
按级别过滤:
# 查看error及以上的日志 journalctl -p err # 查看warning及以上的日志 journalctl -p warning # 查看特定级别的日志(等价于 -p err) journalctl PRIORITY=3
二、常用日志分析命令
2.1 grep家族
grep是最基础的日志搜索工具。
基本搜索:
# 在messages中搜索error grep "error" /var/log/messages # 搜索多个关键词(OR关系) grep -E "error|warning|fail" /var/log/messages # 搜索多个关键词(AND关系) grep "error" /var/log/messages | grep "mysql"
反向搜索,排除关键词:
# 不显示debug日志 grep -v "debug" /var/log/messages # 排除某些关键词 grep -v -E "debug|info" /var/log/messages
显示行号和上下文:
# 显示匹配行的行号 grep -n "error" /var/log/messages # 显示匹配行及前后5行 grep -C 5 "error" /var/log/messages # 只显示匹配行的前面5行 grep -B 5 "error" /var/log/messages # 只显示匹配行的后面5行 grep -A 5 "error" /var/log/messages
统计匹配行数:
grep -c "error" /var/log/messages grep "error" /var/log/messages | wc -l
忽略大小写:
grep -i "error" /var/log/messages
使用正则表达式:
# 匹配IP地址
grep -E "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" /var/log/messages
# 匹配时间戳格式
grep -E "May [0-9]{1,2} [0-9]{2}:[0-9]{2}:[0-9]{2}" /var/log/messages
2.2 awk基础
awk是强大的文本分析工具,适合处理结构化日志。
按列提取数据。messages日志格式通常是"时间 主机名 服务名[PID]: 消息内容":
# 提取第5列及以后的全部内容
awk '{print $5, $6, $7, $8, $9, $10}' /var/log/messages
# 提取特定列
awk '{print $1, $2, $5}' /var/log/messages
条件筛选:
# 第5列等于"sshd"的所有行 awk '$5 == "sshd"' /var/log/messages # 第5列包含"nginx"的所有行 awk '$5 ~ /nginx/' /var/log/messages # 包含error关键词的行 awk '/error/' /var/log/messages
统计出现次数:
# 统计每个服务出现的次数
awk '{print $5}' /var/log/messages | sort | uniq -c | sort -rn
# 统计error出现的次数
awk '/error/' /var/log/messages | wc -l
# 统计每个小时的日志条数
awk '{print $3}' /var/log/messages | cut -d: -f1 | sort | uniq -c
格式化输出:
# 格式化输出
awk '{printf "%-20s %-20s %s
", $1, $2, $5}' /var/log/messages
2.3 sed基础
sed是流编辑器,适合批量替换和编辑。
替换功能:
# 替换所有匹配内容 sed 's/error/ERROR/g' /var/log/messages # 只替换每行第一个匹配 sed 's/error/ERROR/' /var/log/messages # 原地编辑(危险,建议先不用-i测试) sed -i 's/error/ERROR/g' /var/log/messages # 备份后原地编辑 sed -i.bak 's/error/ERROR/g' /var/log/messages
删除功能:
# 删除匹配行 sed '/debug/d' /var/log/messages # 删除空行 sed '/^$/d' /var/log/messages
打印特定行:
# 打印第100行 sed -n '100p' /var/log/messages # 打印第50到100行 sed -n '50,100p' /var/log/messages # 打印最后10行 sed -n '$!p' /var/log/messages
2.4 组合命令技巧
管道组合实现复杂分析:
# 统计error出现次数,按小时分布
grep "error" /var/log/messages | awk '{print $3}' | cut -d: -f1,2 | sort | uniq -c
# 查找最活跃的IP地址
grep "Failed password" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -rn | head -20
# 统计每个用户的登录次数
grep "Accepted password" /var/log/secure | awk '{print $9}' | sort | uniq -c | sort -rn
复杂分析脚本示例。分析SSH暴力破解情况:
#!/bin/bash
# analyze_ssh.sh
echo "=== SSH登录失败统计 ==="
grep "Failed password" /var/log/secure | wc -l
echo ""
echo "=== 失败最多的IP ==="
grep "Failed password" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -rn | head -10
echo ""
echo "=== SSH登录成功统计 ==="
grep "Accepted password" /var/log/secure | wc -l
echo ""
echo "=== 成功登录的用户 ==="
grep "Accepted password" /var/log/secure | awk '{print $9}' | sort | uniq -c | sort -rn | head -10
echo ""
echo "=== 最近10次失败登录 ==="
grep "Failed password" /var/log/secure | tail -10 | awk '{print $1, $2, $3, $11, $13}'
三、常见故障排查场景
3.1 场景一:服务器无法远程连接
服务器无法SSH连接是最常见的故障之一。排查思路是"从本地到远程、从网络到服务"。
第一步:用其他方式(如VNC、IPMI)登录服务器。如果无法登录,说明问题可能在网络层面。
第二步:检查网络连通性。从其他机器测试:
# 测试基础连通性 ping -c 5# 测试端口连通性 nc -zv 22 telnet 22
第三步:检查SSH服务状态。本地执行:
systemctl status sshd
如果服务未运行,尝试启动:
systemctl start sshd systemctl enable sshd
第四步:检查SSH配置:
# 检查配置文件语法 sshd -t # 查看详细日志 tail -50 /var/log/secure | grep sshd journalctl -u sshd --since "30 minutes ago"
第五步:检查端口监听:
netstat -tlnp | grep 22 ss -tlnp | grep 22
第六步:检查防火墙:
# iptables iptables -L -n | grep 22 # firewalld firewall-cmd --list-all | grep ssh # SELinux getenforce semanage port -l | grep ssh
第七步:检查连接数限制:
# 查看当前SSH连接数 ss -tn | grep :22 | wc -l # 查看maxsyslogins限制 cat /etc/security/limits.conf
常见问题及解决方案:
问题:sshd服务无法启动。查看日志:
journalctl -u sshd --no-pager
可能是端口被占用或配置文件错误。
问题:连接被拒绝。检查防火墙:
# CentOS/RHEL systemctl status firewalld firewall-cmd --add-service=ssh --permanent firewall-cmd --reload # 或者直接关闭防火墙测试 systemctl stop firewalld
问题:用户密码正确但无法登录。检查PAM配置和用户shell:
# 检查用户shell grep/etc/passwd # 检查用户是否被锁定 passwd -S # 检查PAM日志 tail -50 /var/log/secure | grep
3.2 场景二:服务启动失败
服务启动失败是另一个常见问题。以Nginx为例讲解排查流程。
第一步:确认服务状态:
systemctl status nginx
第二步:尝试手动启动看错误信息:
# 停止systemd管理 systemctl stop nginx # 手动启动看错误输出 nginx -t # 先检查配置语法 nginx # 手动启动
第三步:查看详细日志:
# Nginx错误日志 tail -100 /var/log/nginx/error.log # 系统日志 journalctl -u nginx --no-pager # messages日志 grep nginx /var/log/messages | tail -50
第四步:检查常见原因:
检查端口占用:
netstat -tlnp | grep :80 ss -tlnp | grep :80
检查配置文件权限:
ls -la /etc/nginx/nginx.conf ls -la /etc/nginx/conf.d/
检查SELinux:
# 检查SELinux状态 getenforce # 如果是Enforcing模式,检查nginx相关权限 semanage port -l | grep http_port ps auxZ | grep nginx
常见Nginx启动失败原因及解决方案:
原因:端口被占用。要么停止占用端口的服务,要么修改Nginx监听端口。
原因:配置文件语法错误。使用nginx -t检查:
nginx -t -c /etc/nginx/nginx.conf
原因:权限问题。可能是SELinux或AppArmor限制。临时关闭SELinux测试:
setenforce 0
原因:缺少依赖库。查看nginx错误日志中是否有"undefined symbol"等错误。
3.3 场景三:磁盘空间不足
磁盘空间不足会导致各种服务异常。排查思路是"定位大文件、清理不必要的文件"。
第一步:查看整体磁盘使用:
df -h
第二步:查找大文件和大目录:
# 查找大于100MB的文件
find / -type f -size +100M -exec ls -lh {} ; 2>/dev/null
# 查找最占空间的目录(根目录下)
du -sh /*
du -sh /var/*
du -sh /home/*
第三步:重点检查日志目录:
du -sh /var/log/*
du -sh /var/log/*/*
# 查找大日志文件
find /var/log -type f -name "*.log" -exec ls -lh {} ; | sort -k5 -rh | head -20
第四步:检查是否被攻击者利用。有些入侵者会在/tmp、/var/tmp等目录存放恶意文件:
ls -la /tmp/ ls -la /var/tmp/ find /tmp -type f -newer /tmp/.security -ls 2>/dev/null
第五步:清理方案:
清理日志文件:
# 清空日志文件(保留文件,只清空内容) > /var/log/messages > /var/log/secure # 删除旧日志 find /var/log -name "*.gz" -mtime +30 -delete # 使用logrotate清理 logrotate -f /etc/logrotate.conf
清理yum缓存:
yum clean all
清理旧的snap版本:
snap list --all snap remove--revision=
清理Docker(如果不需要):
docker system prune -af docker volume prune -f
第六步:防止再次发生。配置logrotate:
cat /etc/logrotate.conf cat /etc/logrotate.d/*
确保关键日志已配置自动轮转。
3.4 场景四:内存泄漏检测
内存泄漏会导致可用内存越来越少,最终影响系统性能。
第一步:检查内存使用趋势。观察free命令输出随时间的变化:
watch -n 5 free -h
第二步:查看进程内存占用,找出可疑进程:
ps aux --sort=-%mem | head -20
第三步:深入分析特定进程。使用pmap查看进程内存映射:
pmap -x| sort -k3 -n -r | head -20
第四步:如果是Java进程,使用jmap分析:
# 生成堆dump(需要停止应用或使用live参数) jmap -dump:format=b,file=heap.bin# 查看堆内存使用 jmap -heap # 查看对象统计 jmap -histo | head -30
第五步:如果是其他进程,使用valgrind检测:
# 安装valgrind yum install valgrind # 分析进程内存(注意:这会显著降低进程性能) valgrind --leak-check=full --log-file=/tmp/valgrind.log
内存泄漏的常见原因:
C/C++程序中malloc但未free
Java程序中对象被长期引用无法回收
配置文件中的缓存设置过大
连接池未正确关闭
线程未正确退出
四、安全日志分析
4.1 SSH登录日志分析
/var/log/secure(CentOS/RHEL)或/var/log/auth.log(Ubuntu/Debian)记录SSH登录信息。
分析成功登录:
# 查看所有成功登录
grep "Accepted password" /var/log/secure
grep "Accepted publickey" /var/log/secure
# 查看最近的成功登录
last
lastlog
# 分析成功登录的来源分布
grep "Accepted password" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -rn | head -10
分析失败登录:
# 查看所有失败登录
grep "Failed password" /var/log/secure
# 统计失败次数
grep "Failed password" /var/log/secure | wc -l
# 找出失败次数最多的IP
grep "Failed password" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -rn | head -10
# 找出被攻击最多的用户
grep "Failed password" /var/log/secure | awk '{print $9}' | sort | uniq -c | sort -rn | head -10
分析暴力破解特征:
# 同一个IP大量失败尝试
grep "Failed password" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -rn | head -10
# 同一用户大量失败尝试
grep "Failed password" /var/log/secure | awk '{print $9}' | sort | uniq -c | sort -rn | head -10
4.2 使用fail2ban自动防护
fail2ban可以自动分析日志并屏蔽恶意IP。
安装和配置:
yum install fail2ban -y # 创建本地配置 cat > /etc/fail2ban/jail.local << 'EOF' [DEFAULT] bantime = 3600 findtime = 600 maxretry = 5 [sshd] enabled = true port = ssh logpath = /var/log/secure maxretry = 3 [nginx-http-auth] enabled = true port = http,https logpath = /var/log/nginx/error.log maxretry = 5 EOF systemctl enable fail2ban systemctl start fail2ban
常用命令:
# 查看fail2ban状态 fail2ban-client status # 查看sshd监狱状态 fail2ban-client status sshd # 手动封禁IP fail2ban-client set sshd banip 1.2.3.4 # 手动解封IP fail2ban-client set sshd unbanip 1.2.3.4 # 查看当前被封禁的IP iptables -L -n | grep fail2ban
4.3 sudo使用日志分析
sudo命令的使用情况也记录在secure日志中:
# 查看sudo使用记录 grep sudo /var/log/secure # 查看sudoers配置 visudo
分析哪个用户使用了sudo以及执行的命令:
grep sudo /var/log/secure | awk -F: '{print $NF}' | sort | uniq -c | sort -rn
4.4 SELinux日志分析
如果系统启用了SELinux,安全相关事件会记录在/var/log/audit/audit.log:
# 查看SELinux拒绝事件 ausearch -m avc -ts recent # 查看特定类型的SELinux事件 ausearch -m avc -se nginx # 将SELinux日志转换为可读格式 ausearch -m avc --raw | audit2allow
查看SELinux状态:
getenforce sestatus
临时切换SELinux模式:
setenforce 0 # 设置为Permissive模式(仅记录,不阻止) setenforce 1 # 设置为Enforcing模式(阻止并记录)
五、应用日志分析
5.1 Nginx日志分析
Nginx日志通常位于/var/log/nginx/目录下,包括access.log和error.log。
分析error.log:
# 查看最近错误
tail -100 /var/log/nginx/error.log
# 搜索特定错误类型
grep "connect() failed" /var/log/nginx/error.log
grep "upstream timed out" /var/log/nginx/error.log
grep "no live upstreams" /var/log/nginx/error.log
# 分析错误趋势
grep "2026/05/13" /var/log/nginx/error.log | awk '{print $NF}' | sort | uniq -c | sort -rn
分析access.log:
# 统计HTTP状态码
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 统计访问量最高的IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 统计访问量最高的URL
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 统计响应时间
awk -F'"' '{print $NF}' /var/log/nginx/access.log | awk '{sum+=$1; count++} END {print "平均响应时间:", sum/count "ms"}'
# 找出最慢的请求
awk -F'"' '{print $NF, $7}' /var/log/nginx/access.log | sort -rn | head -20
5.2 MySQL日志分析
MySQL日志通常位于/var/log/mysql/或/var/log/mariadb/目录。
查看错误日志:
tail -100 /var/log/mysql/error.log grep -E "ERROR|warning" /var/log/mysql/error.log
分析慢查询日志。首先确认慢查询已开启:
SHOW VARIABLES LIKE 'slow_query%'; SHOW VARIABLES LIKE 'long_query_time';
然后分析慢查询日志:
cat /var/log/mysql/slow-query.log # 使用mysqldumpslow工具分析 mysqldumpslow /var/log/mysql/slow-query.log # 找出最慢的查询 mysqldumpslow -s t -t 10 /var/log/mysql/slow-query.log # 找出访问次数最多的查询 mysqldumpslow -s c -t 10 /var/log/mysql/slow-query.log
分析binlog:
# 查看binlog列表 mysql -u root -p -e "SHOW BINARY LOGS;" # 查看当前binlog位置 mysql -u root -p -e "SHOW MASTER STATUS;" # 使用mysqlbinlog查看内容 mysqlbinlog /var/lib/mysql/mysql-bin.000001 | head -100
5.3 Docker日志分析
Docker容器日志通常由containerd或docker处理:
# 查看容器日志(使用docker) docker logs--tail 100 -f # 使用journalctl查看(containerd) journalctl CONTAINER_NAME= --no-pager # 查找错误日志 journalctl CONTAINER_NAME= | grep -i error # 使用crictl查看(containerd) crictl logs
六、日志分析高级技巧
6.1 编写分析脚本
一个实用的日志分析脚本应该具备以下功能:
#!/bin/bash
# analyze_system.sh - 系统日志分析脚本
LOG_FILE="/var/log/messages"
SECURE_LOG="/var/log/secure"
OUTPUT_DIR="/tmp/log_analysis_$(date +%Y%m%d_%H%M%S)"
mkdir -p $OUTPUT_DIR
echo "开始分析日志..."
# 1. 系统错误统计
echo "=== 系统错误和警告 ===" > $OUTPUT_DIR/errors.txt
grep -E "error|warning|critical|alert|emerg" $LOG_FILE >> $OUTPUT_DIR/errors.txt
# 2. SSH登录分析
echo "=== SSH登录分析 ===" > $OUTPUT_DIR/ssh_analysis.txt
echo "成功登录次数: $(grep 'Accepted' $SECURE_LOG | wc -l)" >> $OUTPUT_DIR/ssh_analysis.txt
echo "失败登录次数: $(grep 'Failed' $SECURE_LOG | wc -l)" >> $OUTPUT_DIR/ssh_analysis.txt
echo "" >> $OUTPUT_DIR/ssh_analysis.txt
echo "失败登录Top 10 IP:" >> $OUTPUT_DIR/ssh_analysis.txt
grep 'Failed' $SECURE_LOG | awk '{print $11}' | sort | uniq -c | sort -rn | head -10 >> $OUTPUT_DIR/ssh_analysis.txt
# 3. 磁盘空间分析
echo "=== 磁盘使用情况 ===" > $OUTPUT_DIR/disk_usage.txt
df -h >> $OUTPUT_DIR/disk_usage.txt
echo "" >> $OUTPUT_DIR/disk_usage.txt
echo "大目录 (>1GB):" >> $OUTPUT_DIR/disk_usage.txt
du -sh /var/* 2>/dev/null | sort -rh | awk '$1 ~ /G/ {print}' >> $OUTPUT_DIR/disk_usage.txt
# 4. 内存和CPU状态
echo "=== 系统资源状态 ===" > $OUTPUT_DIR/resources.txt
echo "内存使用:" >> $OUTPUT_DIR/resources.txt
free -h >> $OUTPUT_DIR/resources.txt
echo "" >> $OUTPUT_DIR/resources.txt
echo "CPU和负载:" >> $OUTPUT_DIR/resources.txt
uptime >> $OUTPUT_DIR/resources.txt
# 5. 服务状态
echo "=== 服务状态 ===" > $OUTPUT_DIR/services.txt
systemctl list-units --type=service --state=failed --no-pager >> $OUTPUT_DIR/services.txt
echo ""
echo "分析完成,结果保存在: $OUTPUT_DIR"
ls -la $OUTPUT_DIR
6.2 使用logwatch进行自动化分析
logwatch是一个日志分析工具,可以自动生成日志摘要:
# 安装 yum install logwatch -y # 手动运行 logwatch --output mail --mailto admin@example.com --detail high # 输出到文件 logwatch --output file --filename /tmp/logwatch.txt --detail high # 只分析特定服务 logwatch --service sshd --detail high
配置logwatch定期运行:
# 创建定时任务 crontab -e # 每天早上8点运行日志分析 0 8 * * * /usr/sbin/logwatch --output mail --mailto admin@example.com
6.3 日志集中管理
生产环境中,建议将日志集中管理,便于分析和告警。
使用rsyslog远程日志。配置客户端发送日志到远程服务器:
# /etc/rsyslog.conf *.* @@remote-server:514
配置服务器接收日志:
# /etc/rsyslog.conf module(load="imtcp") input(type="imtcp" port="514") template RemoteLogs,"/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log" *.* ?RemoteLogs
使用ELK Stack分析日志。Elasticsearch + Logstash + Kibana是流行的日志分析平台:
Filebeat:采集日志文件
Logstash:解析和转换日志
Elasticsearch:存储和索引
Kibana:可视化和查询
6.4 日志实时监控和告警
使用inotifywait实时监控日志变化:
# 安装 yum install inotify-tools -y # 监控日志文件变化并告警 inotifywait -m -e modify /var/log/secure | while read path action file; do if grep -q "Failed password" "$path$file"; then echo "检测到SSH失败登录: $(tail -1 $path$file)" | mail -s "SSH登录告警" admin@example.com fi done
七、常见日志模式识别
7.1 识别OOM Killer
当系统内存不足时,内核会触发OOM Killer,杀死进程以释放内存。
查找OOM Killer日志:
# 在dmesg中查找 dmesg | grep -i "out of memory" dmesg | grep -i "killed process" # 在messages中查找 grep -i "oom" /var/log/messages # 查找具体的被杀进程 dmesg -T | grep "killed process"
OOM Killer日志格式:
[Mon May 13 1000 2024] Out of memory: Kill process 12345 (java) score 900 or sacrifice child [Mon May 13 1000 2024] Killed process 12345 (java) total-vm: 8000000kB, anon-rss: 7500000kB, file-rss: 0kB
分析OOM原因:
# 查看被杀进程的详细信息 ps -eo pid,ppid,user,%mem,cmd --sort=-%mem | head -10 # 查看内存使用趋势 free -h vmstat 2 5
7.2 识别磁盘IO问题
查看IO等待相关的日志:
grep -i "io timeout" /var/log/messages grep -i "ext4" /var/log/messages | grep -i error
查看dmesg中的IO错误:
dmesg | grep -i "sd[a-z]" | grep -i error dmesg | grep -i "ata" | grep -i error
7.3 识别网络问题
查找网络相关的错误:
# TCP连接问题 netstat -s | grep -i "retransmit" netstat -s | grep -i "failed" # 网卡状态 dmesg | grep -i "eth0" ip -s link show eth0 # 网络丢包 netstat -i ip -s link show
7.4 识别服务崩溃
查找服务崩溃的日志模式:
# 查找core dump ls -la /var/crash/ find /var/crash -name "core.*" -ls # 查找段错误 grep -i "segfault" /var/log/messages dmesg | grep -i segfault # 查找ABRT报告 ls -la /var/spool/abrt/
八、实战案例
8.1 案例:定位服务器频繁重启的根本原因
背景:某台服务器经常自动重启,平均每天重启2-3次,严重影响业务。
排查过程:
第一步,查看系统日志中的重启记录:
last reboot who -b last | head -20
第二步,查看messages日志中的关键时间点:
# 查看重启前的系统日志 grep -E "May 1[0-9]" /var/log/messages | tail -200
发现重启前有大量OOM Killer日志。
第三步,查看dmesg中的内核日志:
dmesg | grep -i "oom" dmesg | grep -i "kill"
确认是被OOM Killer杀死导致系统不稳定。
第四步,分析是哪个进程被杀死:
dmesg | grep -A 2 "killed process"
发现是MySQL数据库进程被杀死。
第五步,分析内存使用情况:
free -h ps aux --sort=-%mem | head -10
发现可用内存很少,mysqld占用内存过大。
根因:MySQL配置了过大的内存缓冲(innodb_buffer_pool_size设置为16GB),而服务器总内存只有32GB,还运行了其他服务。内存不足触发OOM Killer,系统不稳定。
修复方案:
降低MySQL的innodb_buffer_pool_size:
SET GLOBAL innodb_buffer_pool_size = 8589934592; -- 8GB
永久修改/etc/my.cnf:
innodb_buffer_pool_size = 8G
重启MySQL验证:
systemctl restart mariadb
监控系统内存:
watch -n 5 free -h
总结:服务器频繁重启往往与硬件(电源、散热)、内核(内核panic)、服务(OOM)有关。通过分析系统日志可以快速定位原因。
8.2 案例:从日志中发现入侵痕迹
背景:安全扫描发现某台服务器可能存在入侵,需要排查。
排查过程:
第一步,检查SSH登录日志:
# 查看失败的登录尝试
grep "Failed password" /var/log/secure | tail -100
# 统计失败次数最多的IP
grep "Failed password" /var/log/secure | awk '{print $11}' | sort | uniq -c | sort -rn | head -20
发现某个IP有上万次失败登录,说明可能在尝试暴力破解。
第二步,检查是否有成功的异常登录:
grep "Accepted password" /var/log/secure | awk '{print $9, $11, $12}' | sort | uniq -c | sort -rn
发现有一个陌生的用户登录过,但该用户在/etc/passwd中不存在。
第三步,检查用户操作历史:
# 查看bash历史 cat /var/spool/mail/# 如果有邮件 grep /var/log/secure | tail -50
第四步,检查是否有可疑文件:
# 检查新增的setuid文件 find / -type f -perm -4000 -ls 2>/dev/null # 检查/tmp目录的可疑文件 ls -la /tmp/ find /tmp -type f -newer /tmp/.security -ls 2>/dev/null # 检查隐藏文件 ls -la / | grep "^." find / -name ".*" -type f -ls 2>/dev/null | head -20
根因:攻击者通过SSH暴力破解获得了一个低权限用户的访问权限,并尝试提权。
修复方案:
立即断开该IP的连接:
iptables -I INPUT -s-j DROP
检查是否有新增的恶意文件或进程:
ps aux | grep suspicious lsof | grep suspicious
备份重要数据,重装系统。
加强SSH安全:
# 禁用密码登录,使用密钥 # 编辑 /etc/ssh/sshd_config PasswordAuthentication no PermitRootLogin no systemctl restart sshd
配置fail2ban防护。
总结:安全排查需要仔细分析日志,发现异常行为。关键是平时要做好日志留存和定期审计。
九、总结
日志分析是运维工程师最基本但也是最重要的技能之一。
核心要点:
熟悉日志位置。知道/var/log/下各个文件的用途,messages、secure、dmesg是最常用的三个。
掌握分析工具。grep、awk、sed是最基础的日志分析工具,journalctl是systemd时代的强大工具。
建立分析思路。从时间、关键词、频率、趋势等多个维度分析日志。
形成排查闭环:发现异常 → 定位根因 → 修复问题 → 验证结果 → 总结复盘。
常用命令速查:
# 查看日志 cat /var/log/messages tail -f /var/log/messages journalctl -f journalctl -u--since "1 hour ago" # 搜索 grep "error" /var/log/messages grep -E "error|warning|fail" /var/log/messages awk '/error/ {print $0}' /var/log/messages # 统计 grep "error" /var/log/messages | wc -l awk '{print $5}' /var/log/messages | sort | uniq -c | sort -rn # 分析 last lastlog dmesg | grep -i error ss -s # 安全分析 grep "Failed password" /var/log/secure grep "Accepted" /var/log/secure ausearch -m avc -ts recent
日志分析能力的提升靠的是长期实践。遇到问题时多分析日志,积累经验,形成自己的排查思路和方法论。
全部0条评论
快来发表一下你的评论吧 !