Nginx访问日志分析脚本
分析Nginx访问日志,统计PV/UV、热门页面、状态码分布、响应时间、Top IP等
详细内容
#!/bin/bash
# ==========================================
# Nginx访问日志分析脚本
# 用途:分析Nginx访问日志,输出统计报告
# 使用方法:bash nginx_log_analyzer.sh [日志文件路径]
# ==========================================
LOG_FILE="${1:-/var/log/nginx/access.log}"
echo "========== Nginx日志分析报告 =========="
echo "分析时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "日志文件: $LOG_FILE"
echo ""
if [ ! -f "$LOG_FILE" ]; then
echo "❌ 错误: 日志文件不存在: $LOG_FILE"
exit 1
fi
TOTAL_LINES=$(wc -l < "$LOG_FILE")
echo "日志总行数: $TOTAL_LINES"
echo ""
# 1. PV/UV统计
echo "【1. PV/UV统计】"
PV=$TOTAL_LINES
UV=$(awk '{print $1}' "$LOG_FILE" | sort -u | wc -l)
echo " 总访问量(PV): $PV"
echo " 独立访客(UV): $UV"
echo " 人均访问页数: $(echo "scale=1; $PV / $UV" | bc 2>/dev/null || echo 'N/A')"
echo ""
# 2. 状态码分布
echo "【2. HTTP状态码分布】"
awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -rn | while read count code; do
case "$code" in
2*) echo " ✅ $code: $count 次" ;;
3*) echo " 🔄 $code: $count 次" ;;
4*) echo " ⚠️ $code: $count 次" ;;
5*) echo " ❌ $code: $count 次" ;;
*) echo " ❓ $code: $count 次" ;;
esac
done
echo ""
# 3. Top 10访问IP
echo "【3. Top 10访问IP】"
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10 | awk '{printf " %2d. %-15s %d次
", NR, $2, $1}'
echo ""
# 4. Top 10热门页面
echo "【4. Top 10热门页面】"
awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10 | awk '{printf " %2d. %-50s %d次
", NR, $2, $1}'
echo ""
# 5. 请求方法分布
echo "【5. 请求方法分布】"
awk '{print $6}' "$LOG_FILE" | tr -d '"' | sort | uniq -c | sort -rn | while read count method; do
echo " $method: $count 次"
done
echo ""
# 6. User-Agent统计
echo "【6. 浏览器/设备统计】"
awk -F'"' '{print $6}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -5 | awk '{printf " %2d. %d次 - %s
", NR, $1, substr($0, index($0,$2))}'
echo ""
# 7. 响应时间分析(如果日志包含$request_time)
echo "【7. 响应时间分析】"
if grep -qE '[0-9]+\.[0-9]+$' "$LOG_FILE" 2>/dev/null; then
TIMES=$(awk '{print $NF}' "$LOG_FILE" | grep -E '^[0-9]+\.[0-9]+$' | sort -n)
if [ -n "$TIMES" ]; then
COUNT=$(echo "$TIMES" | wc -l)
AVG=$(echo "$TIMES" | awk '{sum+=$1} END {printf "%.3f", sum/NR}')
MAX=$(echo "$TIMES" | tail -1)
P95=$(echo "$TIMES" | awk -v c="$COUNT" 'BEGIN{target=int(c*0.95)} NR==target{print; exit}')
echo " 总请求数: $COUNT"
echo " 平均响应时间: ${AVG}s"
echo " P95响应时间: ${P95}s"
echo " 最大响应时间: ${MAX}s"
# 慢请求统计
SLOW=$(echo "$TIMES" | awk '$1 > 1' | wc -l)
echo " 慢请求(>1s): $SLOW 次 ($(echo "scale=1; $SLOW * 100 / $COUNT" | bc)%)"
else
echo " 未检测到响应时间数据"
fi
else
echo " 日志格式不包含响应时间字段"
echo " 提示: 在nginx.conf中添加 log_format 包含 \$request_time"
fi
echo ""
# 8. 404页面统计
echo "【8. 404错误页面Top 10】"
awk '$9 == 404 {print $7}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10 | awk '{printf " %2d. %-50s %d次
", NR, $2, $1}'
echo ""
# 9. 按小时统计访问量
echo "【9. 按小时访问量分布】"
awk '{print $4}' "$LOG_FILE" | cut -d: -f2 | sort | uniq -c | sort -k2 -n | while read count hour; do
BAR=$(printf '=%.0s' $(seq 1 $((count/100)) 2>/dev/null))
echo " ${hour}:00 | ${BAR} ${count}"
done
echo ""
echo "========== 分析完成 =========="
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "LOG_FILE", "label": "Nginx\u65e5\u5fd7\u6587\u4ef6\u8def\u5f84", "default": "/var/log/nginx/access.log"}]