awk分析Nginx日志

awk分析Nginx日志

data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">

以下是一个基于 Nginx 访问日志的 AWK 逻辑组合实战示例,模拟实际工作中“多条件筛选异常请求并统计”的场景,包含基础逻辑组合、高级统计及输出格式化。

场景背景

假设我们有一份 Nginx 访问日志 access.log,格式如下(简化版,字段含义对应):

1
2
$1: 客户端IP  $4: 访问时间  $6: 请求方法  $7: 请求路径  $9: 状态码  $10: 响应大小(字节)  

示例日志内容:

1
2
3
4
5
6
192.168.1.1 - - [10/Oct/2023:10:00:00 +0800] "GET /index.html HTTP/1.1" 200 1500  
10.0.0.2 - - [10/Oct/2023:10:01:30 +0800] "POST /login HTTP/1.1" 500 0
192.168.1.3 - - [10/Oct/2023:10:02:15 +0800] "GET /api/data HTTP/1.1" 404 100
10.0.0.2 - - [10/Oct/2023:10:03:00 +0800] "POST /login HTTP/1.1" 500 0
192.168.1.1 - - [10/Oct/2023:10:05:00 +0800] "GET /largefile.zip HTTP/1.1" 200 10485760

需求目标

用 AWK 逻辑组合实现:

筛选两类“异常请求”:

  • 条件A:状态码为 500(服务器错误)且请求方法为 POST 的请求(可能是接口故障)。

  • 条件B:状态码为 200(正常)但响应大小 > 10MB(10485760 字节)的 GET 请求(可能是大文件滥用)。

分别统计两类异常的出现次数,并按 IP 分组统计。

输出格式化报告,包含总次数和 Top IP。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/awk -f  
# 处理 Nginx 日志,筛选并统计异常请求

# 字段对应(根据实际日志格式调整)
# $1: IP $6: 请求方法(如"GET") $9: 状态码 $10: 响应大小

# 逻辑组合筛选异常请求,并统计
{
# 条件A:500错误 + POST请求(提取方法时去除引号,如"POST→POST)
if ($9 == 500 && substr($6, 2, length($6)-2) == "POST") {
typeA_total++ # 总次数+1
typeA_ip[$1]++ # 按IP统计
}
# 条件B:200正常 + GET请求 + 响应大小>10MB(10485760字节)
else if ($9 == 200 && substr($6, 2, length($6)-2) == "GET" && $10 > 10485760) {
typeB_total++ # 总次数+1
typeB_ip[$1]++ # 按IP统计
}
}

# 输出报告(END块汇总结果)
END {
print "===== 异常请求统计报告 ====="
# 输出类型A统计
print "\n1. 服务器错误(500+POST):"
print " 总次数:", typeA_total
print " 主要IP分布:"
for (ip in typeA_ip) {
printf " %-15s 出现 %d 次\n", ip, typeA_ip[ip]
}

# 输出类型B统计
print "\n2. 大文件请求(200+GET+>10MB):"
print " 总次数:", typeB_total
print " 主要IP分布:"
for (ip in typeB_ip) {
printf " %-15s 出现 %d 次\n", ip, typeB_ip[ip]
}
}

执行与输出

保存脚本为 log_analysis.awk,添加执行权限:chmod +x log_analysis.awk

执行:./log_analysis.awk access.log

输出结果:

1
2
3
4
5
6
7
8
9
10
11
12
===== 异常请求统计报告 =====  

1. 服务器错误(500+POST):
总次数: 2
主要IP分布:
10.0.0.2 出现 2 次

2. 大文件请求(200+GET+>10MB):
总次数: 1
主要IP分布:
192.168.1.1 出现 1 次

逻辑组合解析

多条件“与”组合:

  • 条件A用 $9 == 500 && 方法==POST,确保同时满足“状态码500”和“POST请求”。

  • 条件B用 $9 == 200 && 方法==GET && 大小>10MB,三重条件筛选大文件请求。

字符串处理与逻辑结合:

  • 用 substr($6, 2, length($6)-2) 提取请求方法(去除日志中方法外的引号,如 “POST→POST),避免因引号导致匹配失败。

分支逻辑(if-else):

  • 用 else if 区分两类异常,避免重复统计(同一行不会同时属于A和B)。

数组统计:

  • 用关联数组 typeA_ip[$1]++ 按IP分组,实现“多维度统计”(既算总数,又看IP分布)。

实际价值

此示例可直接用于生产环境的日志监控:

  • 快速定位接口故障(500+POST)的频发IP,排查是否为恶意请求;

  • 识别大文件滥用(200+GET+大尺寸)的IP,限制其带宽或访问权限;

  • 通过逻辑组合灵活扩展规则(如添加时间范围 $4 ~ /10:00:00/ 筛选特定时段异常)。

data-ad-format="auto" data-full-width-responsive="true">