日志分析实战:grep/awk/sed 在日志分析中的高阶用法、日志聚合与可视化
日志这东西,说白了就是系统的「黑匣子」。我干了十几年运维和架构,每次线上出问题,第一反应就是翻日志。但很多同学翻日志的方式,还停留在 tail -f 加肉眼扫描的阶段。这哪行?今天我就把压箱底的三板斧——grep、awk、sed 的高阶玩法,连同日志聚合和可视化的思路,一次性倒给你。
一、grep:不只是搜索,更是「手术刀」
很多人觉得 grep 就是 grep 'error' app.log。嗯,这没错,但太糙了。我习惯把它当手术刀用,精准切出病灶。
1. 多条件匹配:既要又要还要
你想找「ERROR」但又不想看到「timeout」的干扰?试试这个:
grep 'ERROR' app.log | grep -v 'timeout'
-v 是反向匹配,相当于「我不要这个」。我在排查一次数据库连接池泄漏时,就用这招过滤掉了大量正常的「Connection timeout」重试日志,才找到真正的「OutOfMemoryError」。
2. 上下文显示:看前后文才完整
单看一行错误,很多时候是猜谜。你需要看它发生前后的上下文:
grep -B 5 -A 10 'NullPointerException' app.log
-B 5 是前5行,-A 10 是后10行。我建议你养成习惯,查异常时至少带上前后各5行,否则很容易误判。
3. 正则匹配:精准定位
比如你想找所有 IP 地址,或者所有 5xx 状态码:
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' access.log
grep -E 'HTTP/1.[01]" [5][0-9]{2}' access.log
-E 启用扩展正则。说实话,正则这东西,不用背,用的时候查一下,多用几次就记住了。
grep -c 统计匹配行数,快速判断问题频率。比如 grep -c 'ERROR' app.log,一眼就知道今天炸了多少次。
二、awk:列处理之王
grep 找行,awk 切列。日志大多是结构化文本,比如用空格或逗号分隔。awk 就是为这种场景生的。
1. 提取特定列
假设你的 access.log 格式是:IP 时间 方法 路径 状态码 响应时间。你想看所有响应时间超过 3 秒的请求:
awk '$6 > 3 {print $1, $4, $6}' access.log
$6 是第六列,$1 是 IP,$4 是路径。这比用 Excel 打开快多了。
2. 条件统计:聚合分析
我想统计每个 IP 的请求次数,按降序排列:
awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log | sort -k2 -rn
这里用了一个数组 count,以 IP 为 key,每出现一次就加 1。最后在 END 块里输出。我在一次 DDoS 排查中,就是用这行命令,一秒锁定了攻击源 IP。
3. 时间范围过滤
日志里时间戳是 [10/Nov/2024:13:45:00 这种格式。我想看 13:45 到 13:50 之间的日志:
awk '/13:4[5-9]:/ || /13:50:/' app.log
正则配合 awk,灵活得很。你想想看,如果日志有几十万行,手动翻到什么时候?
三、sed:流式编辑,批量替换
sed 我用的最多的是「替换」和「删除」。它不修改原文件,除非你加 -i 参数。我建议你刚开始别加 -i,先输出到屏幕看看效果。
1. 批量替换敏感信息
日志里可能有密码、身份证号,需要脱敏:
sed 's/password=[^&]*/password=****/g' app.log
这个正则匹配 password= 后面直到 & 或结尾的内容,替换成星号。我曾经因为日志里泄露了数据库密码,被安全部门约谈……从那以后,我写脚本第一件事就是加脱敏。
2. 删除无用行
比如你想去掉所有 DEBUG 级别的日志,只保留 WARN 和 ERROR:
sed '/DEBUG/d' app.log > clean.log
d 是删除命令。配合正则,可以删掉所有你不关心的行。
3. 在指定行前后插入内容
比如你想在每个 ERROR 行前面加一个分隔线:
sed '/ERROR/i\--------------------------------' app.log
i 是插入,a 是追加。这个小技巧在生成报告时特别好用。
-i 参数在 macOS 和 Linux 上行为不同。macOS 需要 sed -i '' 's/old/new/g' file,Linux 直接 sed -i 's/old/new/g' file。跨平台时小心点。
四、日志聚合:从单机到集群
单机用 grep/awk/sed 没问题。但当你管理几十台服务器,每台都 ssh 上去翻日志?不现实。这时候就需要日志聚合。
1. ELK 三件套
- Elasticsearch:存储和搜索,基于倒排索引,秒级查询
- Logstash:采集和解析,支持各种输入输出插件
- Kibana:可视化展示,图表、仪表盘
我习惯用 Filebeat 替代 Logstash 做采集,更轻量。Logstash 只做解析和过滤,这样资源消耗小很多。
2. 日志格式标准化
聚合的前提是格式统一。我建议团队内部约定一个标准格式,比如:
[时间] [级别] [模块] [线程] [请求ID] - 消息内容
有了请求ID,你就能把一次请求的所有日志串起来。这在微服务排查中简直是救命稻草。
五、可视化:一图胜千言
日志里的数字,光看表格是看不出趋势的。可视化能让你一眼发现问题。
1. 常用图表类型
| 图表类型 | 适用场景 | 示例 |
|---|---|---|
| 折线图 | 趋势分析(QPS、响应时间) | 过去24小时错误数变化 |
| 柱状图 | 对比分析(各接口调用量) | TOP 10 慢接口 |
| 饼图 | 占比分析(错误类型分布) | 404 vs 500 vs 502 占比 |
| 热力图 | 时间分布(流量高峰时段) | 一周内每小时请求量 |
2. Kibana 仪表盘实战
我一般会建三个核心仪表盘:
- 实时监控:最近15分钟的请求量、错误率、平均响应时间
- 趋势分析:过去7天的错误趋势,按模块下钻
- 异常告警:错误率突增、响应时间突增的自动告警
有一次凌晨3点,告警响了,我打开 Kibana 一看,某个接口的错误率从 0.1% 飙到了 30%。再点进去看,全是「Connection refused」。5分钟定位到是下游服务挂了,比等用户投诉快多了。
六、知识体系总览
下面这张图,是我梳理的日志分析知识体系。你可以把它当作学习地图:
这张图把日志分析分成了三层:底层是工具(grep/awk/sed),中间是平台(ELK),顶层是可视化。三者层层递进,缺一不可。我个人建议你从命令行开始练,把基础打牢了,再上平台和可视化,否则容易「知其然不知其所以然」。
好了,这一章的内容就到这。记住,下次线上出问题,别慌,先翻日志。用我今天教你的三板斧,大概率能快速找到线索。