Linux 日志分析命令完全指南 - 实战中即用的必备命令合集
Linux Log Analysis Commands Complete Guide - Essential Commands for Real-World Use
前言:日志分析,为何是系统管理员的核心能力
在运维Linux服务器的过程中,当故障发生时,最先检查的就是日志(Log)。日志就像是系统留下的"黑匣子",记录着什么事件在何时以何种方式发生。无论是追踪安全事件的原因、调试服务故障,还是定位性能瓶颈,日志都是分析的起点。
然而在实际生产环境中,日志文件可能从数GB增长到数十GB,一天积累数百万行也并不罕见。能够从这些海量数据中快速准确地提取所需信息,正是系统管理员和DevOps工程师的核心能力。
本指南将系统性地介绍Linux日志分析所需的所有核心命令。从基础命令到高级单行命令,以可在实际工作中直接复制使用的实战示例为中心进行组织。从初级到中级以上的实战人员都可以按层次进行学习。
1. Linux 日志系统的架构与核心文件
1.1 日志系统的架构
Linux的日志系统大致分为两种体系:
- 传统 syslog 系列:rsyslog、syslog-ng等以文本文件形式记录日志,存储在
/var/log/目录下。 - systemd-journald:在基于systemd的系统中以二进制格式管理日志,使用
journalctl命令进行查询。
大多数现代发行版(RHEL 8+、Ubuntu 20.04+、Debian 11+)都同时使用两套系统。journald先进行一次收集,然后rsyslog再将其保存为文本文件。
1.2 必须了解的核心日志文件
| 日志文件 | 内容 | 主要用途 |
|---|---|---|
/var/log/syslog |
系统整体消息(Debian/Ubuntu) | 常规故障分析 |
/var/log/messages |
系统整体消息(RHEL/CentOS) | 常规故障分析 |
/var/log/auth.log |
认证/登录相关(Debian/Ubuntu) | 安全分析、入侵检测 |
/var/log/secure |
认证/登录相关(RHEL/CentOS) | 安全分析、入侵检测 |
/var/log/kern.log |
内核消息 | 硬件、驱动问题 |
/var/log/dmesg |
启动时内核消息 | 启动问题、硬件检测 |
/var/log/cron |
cron任务执行记录 | 定时任务调试 |
/var/log/maillog |
邮件服务器日志 | 邮件发送/接收追踪 |
/var/log/nginx/ |
Nginx访问/错误日志 | Web流量分析 |
/var/log/apache2/ |
Apache访问/错误日志 | Web流量分析 |
/var/log/mysql/ |
MySQL/MariaDB日志 | DB查询、错误分析 |
/var/log/audit/audit.log |
SELinux/AppArmor审计日志 | 安全审计、策略违规 |
/var/log/boot.log |
服务启动日志 | 服务启动失败分析 |
/var/log/lastlog |
最后登录记录(二进制) | 使用lastlog命令查询 |
/var/log/wtmp |
登录/注销历史(二进制) | 使用last命令查询 |
/var/log/btmp |
失败的登录尝试(二进制) | 使用lastb命令查询 |
ls -la /var/log/确认存在哪些日志文件的习惯。
1.3 理解日志轮转
日志文件由logrotate定期进行轮转(rotation)。之前的日志以.1、.2或.gz扩展名保存:
# 日志轮转示例
/var/log/syslog # 当前日志
/var/log/syslog.1 # 上一个日志(未压缩)
/var/log/syslog.2.gz # 更早的日志(已压缩)
/var/log/syslog.3.gz # 更早以前的日志(已压缩)
# 搜索压缩日志文件时使用 zgrep、zcat
zgrep "error" /var/log/syslog.2.gz
zcat /var/log/syslog.3.gz | grep "kernel"
# 检查 logrotate 配置
cat /etc/logrotate.conf
ls /etc/logrotate.d/
2. 基本日志查看命令
2.1 tail - 实时日志监控的起点
tail是日志分析中最基本且使用最多的命令。尤其是-f选项,是实时监控的核心。
# 查看最后10行(默认)
tail /var/log/syslog
# 查看最后50行
tail -n 50 /var/log/syslog
tail -50 /var/log/syslog # 简写形式
# 实时日志监控(follow)
tail -f /var/log/syslog
# 实时 + 从最近100行开始查看
tail -n 100 -f /var/log/syslog
tail -100f /var/log/syslog # 简写形式
# 同时监控多个文件
tail -f /var/log/syslog /var/log/auth.log
# 文件被替换(rotate)后继续追踪
tail -F /var/log/syslog # 大写 -F:重新打开文件
# 实时过滤特定关键词
tail -f /var/log/syslog | grep --line-buffered "error"
tail -f /var/log/syslog | grep --line-buffered -i "fail\|error\|warn"
tail -f与grep通过管道连接时,务必使用--line-buffered选项。否则可能因缓冲导致输出延迟。
2.2 head - 查看文件头部
# 查看前10行(默认)
head /var/log/syslog
# 查看前30行
head -n 30 /var/log/syslog
# 除最后10行外的全部内容
head -n -10 /var/log/syslog
2.3 cat、less、more - 查看完整文件
# 输出整个文件(仅适用于小文件)
cat /var/log/cron
# 带行号输出
cat -n /var/log/cron
# 按页浏览(最推荐)
less /var/log/syslog
# less 内部快捷键:
# / : 向前搜索
# ? : 向后搜索
# n : 下一个搜索结果
# N : 上一个搜索结果
# G : 跳到文件末尾
# g : 跳到文件开头
# q : 退出
# 在less中实时监控(类似tail -f)
less +F /var/log/syslog
# Ctrl+C切换到浏览模式,Shift+F重新进入追踪模式
less而不是cat。cat会将整个文件加载到内存中,对于数GB的文件可能会给系统带来负担。
2.4 wc - 快速查看日志统计
# 查看总行数
wc -l /var/log/syslog
# 快速了解今天有多少错误
grep -c "error" /var/log/syslog
grep -ci "error\|fail\|critical" /var/log/syslog
# 比较多个日志文件的行数
wc -l /var/log/syslog /var/log/auth.log /var/log/kern.log
3. grep - 日志搜索的核心武器
grep可以说是日志分析中最重要的命令。通过字符串模式匹配,可以从海量日志中快速提取所需信息。
3.1 基本搜索
# 搜索特定字符串
grep "error" /var/log/syslog
# 忽略大小写搜索
grep -i "error" /var/log/syslog
# 显示行号
grep -n "error" /var/log/syslog
# 仅显示匹配计数
grep -c "error" /var/log/syslog
# 仅显示不包含该字符串的行(反向匹配)
grep -v "info" /var/log/syslog
# 完全单词匹配(匹配error,不匹配errorlog)
grep -w "error" /var/log/syslog
3.2 使用正则表达式的高级搜索
# 使用扩展正则表达式(-E 或 egrep)
grep -E "error|fail|critical" /var/log/syslog
# 搜索IP地址模式
grep -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /var/log/auth.log
# 过滤特定时段的日志(例如:凌晨3点)
grep "^Mar 7 03:" /var/log/syslog
# 日期 + 时间范围(2点~5点)
grep -E "^Mar 7 0[2-5]:" /var/log/syslog
# 提取SSH登录失败记录
grep "Failed password" /var/log/auth.log
# 追踪特定用户的sudo命令
grep "sudo.*username" /var/log/auth.log
3.3 上下文搜索 - 了解错误前后的状况
# 显示匹配行之后5行(After)
grep -A 5 "kernel panic" /var/log/kern.log
# 显示匹配行之前3行(Before)
grep -B 3 "OOM" /var/log/syslog
# 前后各显示5行(Context)
grep -C 5 "segfault" /var/log/syslog
# 复合条件:包含error且与nginx相关
grep "error" /var/log/syslog | grep "nginx"
# 同时搜索多个文件
grep -r "connection refused" /var/log/
grep -rl "connection refused" /var/log/ # 仅输出文件名
3.4 在压缩日志中搜索
# 直接在gz压缩文件中搜索
zgrep "error" /var/log/syslog.2.gz
# 查看压缩文件内容
zcat /var/log/syslog.2.gz | less
# 同时搜索当前和历史日志
zgrep "error" /var/log/syslog /var/log/syslog.1 /var/log/syslog.*.gz
4. awk - 日志数据提取与处理的利器
awk是一种专为按字段分割和处理文本而优化的工具。在提取日志中的特定列或按条件进行统计时非常强大。
4.1 基本字段提取
# syslog格式:日期 主机 进程:消息
# $1=月, $2=日, $3=时间, $4=主机, $5=进程
# 仅提取时间和消息
awk '{print $3, $5, $0}' /var/log/syslog | tail -20
# 仅输出特定字段(Nginx access log示例)
# 格式:IP - - [日期] "请求" 状态码 大小 "Referer" "UA"
awk '{print $1, $9}' /var/log/nginx/access.log # IP和状态码
# 处理制表符分隔文件
awk -F'\t' '{print $1, $3}' logfile.tsv
# 逗号分隔(CSV)
awk -F',' '{print $1, $NF}' logfile.csv # 第一个和最后一个字段
4.2 条件过滤
# 仅提取HTTP 500错误(Nginx/Apache)
awk '$9 == 500' /var/log/nginx/access.log
# 所有500系列错误
awk '$9 >= 500 && $9 < 600' /var/log/nginx/access.log
# 仅响应大小超过1MB的
awk '$10 > 1048576' /var/log/nginx/access.log
# 仅特定IP的请求
awk '$1 == "192.168.1.100"' /var/log/nginx/access.log
# 包含特定字符串的行(类似grep)
awk '/error/' /var/log/syslog
awk '/error/ && /nginx/' /var/log/syslog # AND条件
awk '/error/ || /warn/' /var/log/syslog # OR条件
4.3 汇总与统计
# 按IP统计请求次数(Top访问IP)
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 仅用awk进行IP计数
awk '{ip[$1]++} END {for (i in ip) print ip[i], i}' /var/log/nginx/access.log | sort -rn | head -20
# 按状态码统计数量
awk '{code[$9]++} END {for (c in code) print c, code[c]}' /var/log/nginx/access.log | sort -k2 -rn
# 按时段统计请求数(每小时)
awk '{split($4, a, ":"); hour=a[2]; h[hour]++} END {for (i in h) print i, h[i]}' /var/log/nginx/access.log | sort
# 总传输字节数汇总
awk '{sum += $10} END {printf "Total: %.2f GB\n", sum/1024/1024/1024}' /var/log/nginx/access.log
# 按URL路径统计请求数(不区分GET/POST)
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -30
4.4 实战单行命令
# 查找慢请求(假设日志格式包含响应时间)
# 如果log_format中$request_time是最后一个字段:
awk '{if ($NF > 3.0) print $0}' /var/log/nginx/access.log
# 计算每分钟请求数
awk '{split($4,a,"[:/]"); min=a[2]":"a[3]":"a[4]" "a[5]":"a[6]; m[min]++} END {for (i in m) print i, m[i]}' /var/log/nginx/access.log | sort | tail -20
# 计算错误率
awk '{total++; if ($9 >= 400) errors++} END {printf "Total: %d, Errors: %d, Rate: %.2f%%\n", total, errors, (errors/total)*100}' /var/log/nginx/access.log
5. sed - 日志文本转换与提取
sed是流编辑器,在转换日志数据或提取特定范围时非常有用。
5.1 基本模式替换与提取
# 特定字符串替换(用于输出)
sed 's/error/ERROR/gi' /var/log/syslog | head
# 仅输出特定范围的行
sed -n '100,200p' /var/log/syslog # 第100~200行
# 仅提取特定模式之间的内容
sed -n '/Start of backup/,/End of backup/p' /var/log/syslog
# 提取特定时间范围
sed -n '/Mar 7 14:00/,/Mar 7 15:00/p' /var/log/syslog
# 删除空行
sed '/^$/d' /var/log/application.log
# 删除注释行(#)
sed '/^#/d' /etc/rsyslog.conf
# IP地址掩码(用于安全报告)
sed -E 's/([0-9]+\.[0-9]+\.[0-9]+\.)[0-9]+/\1***/g' /var/log/auth.log
5.2 多重命令与高级用法
# 一次执行多个替换
sed -e 's/error/ERROR/gi' -e 's/warning/WARNING/gi' /var/log/syslog
# 删除特定行(排除第1~5行后输出)
sed '1,5d' /var/log/syslog
# 日期格式转换示例
echo "2026/03/07 14:30:00" | sed 's|\([0-9]*\)/\([0-9]*\)/\([0-9]*\)|\1-\2-\3|'
# 仅输出包含特定模式的行(类似grep)
sed -n '/OOM/p' /var/log/syslog
6. sort、uniq、cut - 日志数据排序与汇总
这三个命令单独使用时也很有用,但通过管道组合使用时才能发挥真正的威力。
6.1 sort - 排序
# 基本排序(字母顺序)
sort /var/log/auth.log
# 逆序排列
sort -r /var/log/auth.log
# 按数字排序
sort -n data.log
# 按特定字段排序(第3个字段,数字逆序)
sort -t' ' -k3 -rn access.log
# 按日期排序
sort -k1,1M -k2,2n /var/log/syslog # 月(Month)+ 日(数字)
6.2 uniq - 去重与计数
# 去重(必须与sort配合使用!)
sort /var/log/auth.log | uniq
# 显示重复次数
sort /var/log/auth.log | uniq -c
# 按重复次数重新排序(频率排序)
sort /var/log/auth.log | uniq -c | sort -rn
# 仅显示重复的行
sort /var/log/auth.log | uniq -d
# 仅显示唯一的行(只出现1次)
sort /var/log/auth.log | uniq -u
uniq仅去除连续的重复行。务必先执行sort再使用uniq,才能得到正确的结果。
6.3 cut - 字段截取
# 按特定分隔符提取字段
cut -d' ' -f1 /var/log/nginx/access.log # 仅提取IP
cut -d':' -f1 /etc/passwd # 仅提取用户名
# 按字符位置提取
cut -c1-15 /var/log/syslog # 前15个字符(日期时间)
# 同时提取多个字段
cut -d' ' -f1,4,7 /var/log/nginx/access.log # 第1、4、7个字段
6.4 组合管道实战示例
# SSH登录失败IP Top 10
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# 按时段统计错误数量
grep -i "error" /var/log/syslog | awk '{print $3}' | cut -d: -f1 | sort | uniq -c | sort -rn
# Nginx请求URL Top 20
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# 唯一IP访问数
awk '{print $1}' /var/log/nginx/access.log | sort -u | wc -l
# 按日期统计日志行数趋势
awk '{print $1, $2}' /var/log/syslog | sort | uniq -c
7. journalctl - systemd日志分析的全面指南
在基于systemd的系统中,journalctl是最强大的日志查看工具。它以结构化形式查询二进制日志,并原生支持多种过滤功能。
7.1 基本查询
# 查看全部日志
journalctl
# 从最新的日志逆序查看
journalctl -r
# 仅查看最近50行
journalctl -n 50
# 实时监控(与tail -f相同)
journalctl -f
# 特定启动会话的日志
journalctl -b # 当前启动
journalctl -b -1 # 上一次启动
journalctl --list-boots # 启动历史列表
# 不使用分页器输出(用于脚本)
journalctl --no-pager
7.2 基于时间的过滤
# 特定日期之后
journalctl --since "2026-03-07"
# 特定时间范围
journalctl --since "2026-03-07 14:00" --until "2026-03-07 16:00"
# 相对时间
journalctl --since "1 hour ago"
journalctl --since "30 min ago"
journalctl --since "2 days ago"
journalctl --since yesterday
journalctl --since today
7.3 基于服务/单元的过滤
# 仅查看特定服务的日志
journalctl -u nginx.service
journalctl -u sshd.service
journalctl -u mysql.service
# 同时查看多个服务
journalctl -u nginx.service -u php-fpm.service
# 实时监控特定服务
journalctl -u nginx.service -f
# 特定服务的最近错误
journalctl -u nginx.service -p err -n 50
7.4 优先级(严重程度)过滤
# 按严重程度级别过滤
# 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug
journalctl -p emerg # 紧急(系统不可用)
journalctl -p alert # 需要立即处理
journalctl -p crit # 严重状态
journalctl -p err # 错误(最常用)
journalctl -p warning # 警告
# 指定范围(仅crit及以上的严重日志)
journalctl -p crit..emerg
# 服务 + 严重程度 + 时间组合
journalctl -u sshd.service -p err --since "1 hour ago"
7.5 输出格式控制
# JSON格式输出(便于解析)
journalctl -u nginx.service -o json-pretty -n 5
# 简洁的单行格式
journalctl -o short-precise
# 可用的输出格式
# short : 默认syslog风格
# short-precise : 微秒级时间
# short-iso : ISO 8601格式时间
# verbose : 显示所有字段
# json : JSON格式(单行)
# json-pretty : JSON格式(缩进)
# cat : 仅消息内容(无时间戳)
# 基于特定字段的过滤
journalctl _COMM=sshd # 进程名
journalctl _PID=1234 # PID
journalctl _UID=0 # root用户
journalctl _HOSTNAME=webserver01 # 主机名
7.6 内核日志与磁盘使用量
# 仅内核消息(类似dmesg)
journalctl -k
journalctl --dmesg
# 查看日志磁盘使用量
journalctl --disk-usage
# 清理日志(删除旧日志)
sudo journalctl --vacuum-time=7d # 删除超过7天的日志
sudo journalctl --vacuum-size=500M # 删除超过500MB的部分
8. 按实战场景分类的日志分析
8.1 SSH暴力破解攻击分析
# 检查失败的SSH登录尝试
grep "Failed password" /var/log/auth.log | tail -20
# 提取攻击IP并按频率排序
grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -20
# 分析特定IP的尝试时段
grep "Failed password" /var/log/auth.log | \
grep "192.168.1.100" | awk '{print $1, $2, $3}'
# 确认成功的登录
grep "Accepted" /var/log/auth.log | tail -20
# 使用异常用户名的攻击尝试
grep "Invalid user" /var/log/auth.log | \
awk '{print $8}' | sort | uniq -c | sort -rn | head -20
# 按时段统计攻击频率(每小时)
grep "Failed password" /var/log/auth.log | \
awk '{print $3}' | cut -d: -f1 | sort | uniq -c | sort -rn
# 使用journalctl分析SSH
journalctl -u sshd.service -p warning --since "24 hours ago" --no-pager
8.2 Web服务器故障分析(Nginx/Apache)
# 定位500错误发生时间
grep '" 500 ' /var/log/nginx/access.log | tail -30
# 计算5xx错误比率
awk '{total++; if ($9 ~ /^5/) err++} END {printf "Total: %d, 5xx: %d (%.2f%%)\n", total, err, err/total*100}' \
/var/log/nginx/access.log
# 分析错误发生的URL模式
grep '" 500 ' /var/log/nginx/access.log | \
awk '{print $7}' | sort | uniq -c | sort -rn | head -20
# 分析Nginx错误日志
grep "error" /var/log/nginx/error.log | tail -30
# 检查upstream超时
grep "upstream timed out" /var/log/nginx/error.log | wc -l
# 计算每秒请求数(RPS)
awk '{split($4,a,"[:/]"); sec=a[4]" "a[5]":"a[6]":"a[7]; s[sec]++} END {for (i in s) print i, s[i]}' \
/var/log/nginx/access.log | sort | tail -20
# 特定时段的慢请求(request_time为最后一个字段)
awk '$NF > 5.0 {print $4, $7, $NF}' /var/log/nginx/access.log | tail -20
8.3 磁盘I/O及OOM(内存不足)分析
# 检查OOM Killer终止进程的历史
grep -i "oom" /var/log/syslog
grep "Out of memory" /var/log/syslog
dmesg | grep -i "oom"
# 被OOM终止的进程列表
grep "Killed process" /var/log/syslog | \
awk -F'[()]' '{print $2}' | sort | uniq -c | sort -rn
# 使用journalctl检查OOM
journalctl -k | grep -i "oom"
journalctl -k | grep "Out of memory"
# 磁盘相关错误
grep -i "I/O error" /var/log/syslog
grep -i "ext4.*error" /var/log/syslog
dmesg | grep -i "error"
# 检测文件系统切换为只读
grep "Remounting filesystem read-only" /var/log/syslog
8.4 服务启动/停止/崩溃追踪
# 服务启动/停止历史
journalctl -u nginx.service | grep -i "started\|stopped\|failed"
# 分析服务失败原因
systemctl status nginx.service
journalctl -u nginx.service --since "10 min ago" -p err
# 分析服务重启频率
journalctl -u mysql.service | grep -c "Started"
# 检查核心转储
journalctl | grep "core dump"
coredumpctl list # 使用systemd-coredump时
# 启动失败的服务列表
systemctl --failed
8.5 cron任务调试
# 查看cron执行历史
grep CRON /var/log/syslog
grep CRON /var/log/cron # RHEL/CentOS
# 检查特定用户的cron执行
grep "CRON.*username" /var/log/syslog
# 仅查看cron错误
grep CRON /var/log/syslog | grep -i "error\|fail"
# 使用journalctl查看cron
journalctl -u cron.service --since today
# 检查特定脚本的cron执行
grep "backup.sh" /var/log/syslog
9. 高级分析技巧与单行命令集锦
9.1 使用xargs和find进行多文件分析
# 在最近24小时内修改的日志文件中搜索error
find /var/log -name "*.log" -mtime -1 -exec grep -l "error" {} \;
# 在所有日志文件中搜索特定IP
find /var/log -type f -name "*.log" | xargs grep -l "192.168.1.100" 2>/dev/null
# 查找超过特定大小的日志文件
find /var/log -type f -size +100M -exec ls -lh {} \;
# 清理旧日志文件(30天以上)
find /var/log -name "*.gz" -mtime +30 -exec ls -la {} \;
9.2 使用while read循环逐行处理
# 逐个处理失败IP(例如:生成封禁列表)
grep "Failed password" /var/log/auth.log | \
awk '{print $(NF-3)}' | sort -u | \
while read ip; do
count=$(grep -c "$ip" /var/log/auth.log)
echo "$ip: $count attempts"
done
# 特定错误模式出现时发出警报
tail -f /var/log/syslog | while read line; do
echo "$line" | grep -q "CRITICAL" && echo "ALERT: $line" >> /tmp/alerts.log
done
9.3 结合date命令进行时间分析
# 仅提取最近1小时的日志(syslog格式)
SINCE=$(date -d '1 hour ago' '+%b %e %H')
awk -v since="$SINCE" '$0 >= since' /var/log/syslog
# 搜索昨天的日志
YESTERDAY=$(date -d yesterday '+%b %e')
grep "^$YESTERDAY" /var/log/syslog
# 按分钟统计请求数趋势(最近1小时)
awk '{print substr($4,14,5)}' /var/log/nginx/access.log | sort | uniq -c | tail -60
9.4 实战常用单行命令精选
# === 安全分析 ===
# 1. SSH暴力攻击IP Top 10 + 无GeoIP频率分析
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
# 2. 当前活跃的SSH会话
who | grep pts
ss -tnp | grep :22
# 3. sudo命令使用历史
grep "COMMAND" /var/log/auth.log | awk -F: '{print $NF}' | sort | uniq -c | sort -rn | head -20
# 4. 异常端口连接尝试
grep "refused connect" /var/log/syslog | awk '{print $NF}' | sort | uniq -c | sort -rn
# === 性能分析 ===
# 5. Nginx响应码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 6. 按时段统计流量(每小时)
awk '{split($4,a,":"); print a[2]":00"}' /var/log/nginx/access.log | sort | uniq -c
# 7. 生成最大响应的URL
awk '{print $10, $7}' /var/log/nginx/access.log | sort -rn | head -20
# 8. 带宽使用量计算(按日)
awk '{sum+=$10} END {printf "%.2f GB\n", sum/1024/1024/1024}' /var/log/nginx/access.log
# === 故障分析 ===
# 9. 最近错误日志综合(去重,按频率排序)
grep -i "error\|fail\|critical\|fatal" /var/log/syslog | \
sed 's/^.*\] //' | sort | uniq -c | sort -rn | head -30
# 10. 按服务统计重启频率
journalctl --since "7 days ago" | grep "Started" | \
awk '{for(i=5;i<=NF;i++) printf $i" "; print ""}' | sort | uniq -c | sort -rn | head -20
# 11. 内核panic/OOPS检查
journalctl -k -p crit --since "7 days ago"
dmesg -T | grep -i "panic\|oops\|bug\|error"
# 12. 磁盘满警告相关日志
grep -i "no space\|disk full\|ENOSPC" /var/log/syslog
10. 日志监控自动化
10.1 简单的日志监控脚本
#!/bin/bash
# log_monitor.sh - 日志监控与告警脚本
LOG_FILE="/var/log/syslog"
ALERT_PATTERNS="error|critical|fatal|panic|OOM|segfault"
ALERT_LOG="/var/log/alert_monitor.log"
CHECK_INTERVAL=60
echo "[$(date)] Log monitor started for $LOG_FILE" | tee -a "$ALERT_LOG"
tail -Fn0 "$LOG_FILE" | while read line; do
if echo "$line" | grep -qiE "$ALERT_PATTERNS"; then
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TIMESTAMP] ALERT: $line" | tee -a "$ALERT_LOG"
# 在此处添加告警(邮件、Slack等)
# echo "$line" | mail -s "Log Alert" admin@example.com
fi
done
10.2 使用logwatch生成每日报告
# 安装logwatch
sudo apt install logwatch # Debian/Ubuntu
sudo yum install logwatch # RHEL/CentOS
# 生成每日报告
logwatch --detail High --range today --output stdout
# 通过邮件发送
logwatch --detail High --range yesterday --mailto admin@example.com --format html
# 仅分析特定服务
logwatch --service sshd --detail High --range today
10.3 multitail - 多日志实时监控
# 安装multitail
sudo apt install multitail
# 同时监控多个日志(分屏显示)
multitail /var/log/syslog /var/log/auth.log
# 颜色高亮 + 过滤
multitail -ci green /var/log/nginx/access.log -ci red /var/log/nginx/error.log
# 应用颜色方案和过滤器
multitail -e "error" /var/log/syslog -e "Failed" /var/log/auth.log
10.4 lnav - 结构化日志分析器
# 安装lnav
sudo apt install lnav
# 基本使用(自动格式检测)
lnav /var/log/syslog
# 同时分析多个文件
lnav /var/log/syslog /var/log/auth.log
# 在lnav内部使用SQL查询
# ;SELECT log_time, log_body FROM syslog_log WHERE log_body LIKE '%error%' LIMIT 20
# 自动支持压缩文件
lnav /var/log/syslog.*.gz
lnav能够自动检测日志格式,并支持颜色区分、时间线、直方图和SQL查询等功能,是一款功能非常强大的基于终端的日志分析器。当需要在终端长时间分析日志时,它是最佳选择。
11. 日志分析最佳实践
11.1 高效的日志分析习惯
- 从全局视角开始:先用
wc -l了解规模 -> 用grep -c确认错误频率 -> 再进行详细分析 - 缩小时间范围:以故障发生时间点前后为范围缩小分析范围,可以减少不必要的噪音。
- 逐步构建管道:不要一次性编写复杂的单行命令,而是逐步添加管道并确认结果。
- 善用alias:将常用的日志分析命令在
~/.bashrc中注册为alias,可以提高效率。 - 用tee保存中间结果:使用
command | tee /tmp/result.txt | next_command可以在将中间结果保存到文件的同时继续管道处理。
11.2 实用的bash alias设置
# 添加到~/.bashrc的日志分析alias
alias syslog='tail -f /var/log/syslog'
alias authlog='tail -f /var/log/auth.log'
alias nginxlog='tail -f /var/log/nginx/access.log'
alias nginxerr='tail -f /var/log/nginx/error.log'
alias logerror='grep -i "error\|fail\|critical" /var/log/syslog | tail -50'
alias sshfail='grep "Failed password" /var/log/auth.log | awk '\''{print $(NF-3)}'\'' | sort | uniq -c | sort -rn | head -20'
alias topip='awk '\''{print $1}'\'' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20'
alias jlog='journalctl -f'
alias jerr='journalctl -p err --since "1 hour ago" --no-pager'
11.3 安全注意事项
- 日志文件权限管理:日志文件可能包含敏感信息(IP、用户名、查询参数),请设置适当的权限(640或更低)。
- 日志完整性保护:入侵者可能会删除/篡改日志,因此重要服务器应同时采用远程日志收集(rsyslog远程转发、ELK、Loki等)。
- 日志保留策略:考虑法律要求和磁盘容量,适当配置
logrotate和保留期限。 - 个人信息注意:日志中包含的个人信息(IP、邮箱等)必须按照相关隐私法规进行妥善管理。
12. 命令快速参考速查表
| 用途 | 命令 |
|---|---|
| 实时监控 | tail -f /var/log/syslog |
| 关键词实时过滤 | tail -f /var/log/syslog | grep --line-buffered "error" |
| 错误计数 | grep -ci "error" /var/log/syslog |
| 错误上下文 | grep -C 5 "error" /var/log/syslog |
| 按IP统计访问次数 | awk '{print $1}' access.log | sort | uniq -c | sort -rn |
| HTTP状态码分布 | awk '{print $9}' access.log | sort | uniq -c | sort -rn |
| SSH攻击IP | grep "Failed password" auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn |
| 按时段统计错误 | grep "error" syslog | awk '{print $3}' | cut -d: -f1 | sort | uniq -c |
| 服务日志 | journalctl -u nginx.service -p err --since "1h ago" |
| 内核错误 | journalctl -k -p err |
| OOM检查 | dmesg -T | grep -i "oom\|killed process" |
| 磁盘错误 | grep -i "I/O error\|read-only" /var/log/syslog |
| 压缩日志搜索 | zgrep "error" /var/log/syslog.*.gz |
| 日志行数 | wc -l /var/log/syslog |
| 日志磁盘使用量 | journalctl --disk-usage |
总结:日志分析的关键在于实战经验
Linux日志分析仅仅了解工具和命令是不够的。在实际故障场景中,先检查哪个日志文件、用什么模式进行过滤、如何解读结果——这种实战经验才是最重要的。
请在自己的服务器环境中亲自运行本指南中介绍的命令。grep与awk的组合、journalctl的各种过滤选项、sort | uniq -c | sort -rn管道,一旦熟练掌握,在任何日志分析场景中都能快速应对。
尤其需要牢记的核心原则如下:
- 始终从缩小时间范围开始 - 不要翻查整个日志,而是集中在故障发生时间点前后。
- 逐步构建管道 - 每添加一步都确认结果后再继续。
- 常用命令保存为alias - 在紧急情况下,使用alias比回忆命令更快。
- 同步使用远程日志收集 - 仅依赖本地日志无法保障安全性和可用性。
- 定期检查日志 - 不要等到故障发生后才查看日志,养成平时也监控日志趋势的习惯非常重要。
日志分析能力对于系统管理员、DevOps工程师、SRE和安全工程师来说都是必不可少的核心能力。请立即在终端中运行今天学到的命令,建立属于自己的分析工作流程。