Nginx日志分析:编写Shell脚本进行全面日志统计
Nginx
是一个高性能的HTTP
和反向代理服务器,也是一个IMAP/POP3/SMTP
代理服务器。无论是在大流量的网站还是小型的个人博客中,Nginx
都得到了广泛应用。在实际生产环境中,对Nginx
日志的分析有助于我们了解网站的访问情况,发现潜在问题并进行优化。本文将通过编写Shell脚本,实现对Nginx
日志的全面统计分析。
Nginx日志格式
首先,我们需要确保Nginx日志格式与以下格式类似:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
假设我们的日志文件名为access.log
。
Shell脚本实现
接下来,我们编写一个Shell脚本,对Nginx
日志进行统计分析。这个脚本包括以下功能:
- 统计各种状态码的数量
- 统计访问最多的
Referer
- 统计访问最高的
URI
- 统计访问最多的IP和
User-Agent
- 统计每分钟的请求数、流量、请求时间、状态码等
脚本代码实现
- 统计各种状态码的数量
awk '
{
Arry[$12] += 1;
total++;
}
END {
for (s in Arry) {
printf "%d\t%.4f\t%s\n", Arry[s], Arry[s] / total, s
}
}
' $LOG_FILE | sort -nr -k 1,1
Arry[$9] += 1;
:
$12
是日志文件的第十二个字段,通常表示 HTTP 状态码。Arry
是一个关联数组,以 HTTP 状态码为键,将每个状态码出现的次数累加到数组Arry
中。Arry[$9] += 1;
表示状态码$9
出现的次数加 1。total++;
:
- 记录总的日志行数。
for (s in Arry)
:
- 遍历数组
Arry
中的每个状态码s
。printf "%d\t%.4f\t%s\n", Arry[s], Arry[s] / total, s
:
- 打印每个状态码的出现次数、占比和状态码本身。
Arry[s]
是状态码s
出现的次数。Arry[s] / total
是该状态码出现的比例(占总请求数的百分比)。s
是状态码。- 输出格式为:出现次数
\t
比例\t
状态码。
运行上述的命令,输出如下结果:
- 统计访问最多的
Referer
awk -F\" '
{
Arry[$4] += 1; # 将每个引用的字段($4)出现的次数累加到数组Arry中
total++; # 记录总的日志行数
}
END {
for (s in Arry) { # 遍历数组Arry中的每个引用字段
printf "%d\t%.4f\t%s\n", Arry[s], Arry[s] / total, s # 打印每个引用字段的出现次数、占比和引用字段本身
}
}
' $LOG_FILE | sort -nr -k 1,1 # 按出现次数降序排序
执行上述命令后,输出如下图的结果:
- 统计访问最高的
URI
awk '
{
Arry[$9] += 1; # 将每个引用的字段($18)出现的次数累加到数组Arry中
total++; # 记录总的日志行数
}
END {
for (s in Arry) { # 遍历数组Arry中的每个引用字段
printf "%d\t%.4f\t%s\n", Arry[s], Arry[s] / total, s # 打印每个引用字段的出现次数、占比和引用字段本身
}
}
' $LOG_FILE | sort -nr -k 1 # 按出现次数降序排序
执行上述命令后,输出如下图的结果:
- 统计访问最多的IP和
User-Agent
- 统计最多IP访问次数
awk '
{
Arry[$1] += 1; # 将每个IP地址出现的次数累加到数组Arry中
total++; # 记录总的日志行数
}
END {
for (s in Arry) { # 遍历数组Arry中的每个IP地址
printf "%d\t%.4f\t%s\n", Arry[s], Arry[s] / total, s # 打印每个IP地址的出现次数、占比和IP地址本身
}
}
' $LOG_FILE | sort -nr -k 1,1
执行上述命令后,输出如下图的结果:
- 统计最多访问的
User-Agent
awk '
{
Arry[$18] += 1; # 将每个引用的字段($18)出现的次数累加到数组Arry中
total++; # 记录总的日志行数
}
END {
for (s in Arry) { # 遍历数组Arry中的每个引用字段
printf "%d\t%.4f\t%s\n", Arry[s], Arry[s] / total, s # 打印每个引用字段的出现次数、占比和引用字段本身
}
}
' $LOG_FILE | sort -nr -k 1 # 按出现次数降序排序
执行上述命令后,输出如下图的结果:
- 统计每分钟的请求数、流量、请求时间、状态码等
awk -F '|' '
BEGIN {
printf "时间\t数量\t流量[MB]\t请求时间\t20x\t30x\t40x\t50x\t60x\n"
}
{
# 提取时间的分钟部分
minute = substr($2, 12, 5)
# 累计流量、请求数和请求时间
tms[minute] += $13
cnt[minute] += 1
reqt[minute] += $15
# 统计状态码
status_code = $9
if (status_code ~ /^2/) { sc20x[minute]++ }
else if (status_code ~ /^3/) { sc30x[minute]++ }
else if (status_code ~ /^4/) { sc40x[minute]++ }
else if (status_code ~ /^5/) { sc50x[minute]++ }
else { sc60x[minute]++ }
}
END {
for (t in tms) {
printf "%s\t%d\t%.4f\t%.4f\t%d\t%d\t%d\t%d\t%d\n",
t,
cnt[t],
tms[t] / 1024 / 1024,
(cnt[t] > 0 ? reqt[t] / cnt[t] : 0),
sc20x[t],
sc30x[t],
sc40x[t],
sc50x[t],
sc60x[t]
}
}
' "$LOG_FILE"
执行上述命令后,输出如下结果:
总结
通过上述Shell脚本,我们可以快速、全面地分析Nginx日志,了解网站的访问情况和性能表现。这不仅有助于我们发现潜在问题,还能为后续的优化工作提供有力的数据支持。在实际应用中,你可以根据自己的需求,进一步扩展和定制这个脚本。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 攻城狮小林
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果