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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| # grep 是筛选的域名 awk中的$5是判断的状态码 sort中的15是指的upstream_response_time 当然也可以统计request_time的时间 #!/bin/bash
# 默认配置 LOG_FILE="/var/log/nginx/access.log" # Nginx日志文件路径 DOMAIN="" # 筛选的域名(空表示所有) STATUS_CODE="200" # 状态码(空表示所有) TOP_N=10 # 显示前N条 TIME_FIELD="upstream_response_time" # 统计的时间字段(request_time/upstream_response_time) TIME_THRESHOLD=0 # 最小耗时阈值(秒,0表示不限制)
# 显示帮助信息 usage() { echo "用法: $0 [选项]" echo "分析Nginx日志中耗时较长的接口" echo "选项:" echo " -f <日志文件> 指定Nginx日志文件路径(默认: $LOG_FILE)" echo " -d <域名> 筛选特定域名(如 zhhll.icu)" echo " -s <状态码> 筛选特定状态码(如 200, 500)" echo " -n <数量> 显示前N条记录(默认: $TOP_N)" echo " -t <时间字段> 时间字段(request_time/upstream_response_time, 默认: $TIME_FIELD)" echo " -T <阈值> 最小耗时阈值(秒,默认: $TIME_THRESHOLD)" echo " -h 显示帮助信息" exit 1 }
# 解析命令行参数 while getopts "f:d:s:n:t:T:h" opt; do case $opt in f) LOG_FILE="$OPTARG" ;; d) DOMAIN="$OPTARG" ;; s) STATUS_CODE="$OPTARG" ;; n) TOP_N="$OPTARG" ;; t) TIME_FIELD="$OPTARG" ;; T) TIME_THRESHOLD="$OPTARG" ;; h) usage ;; *) usage ;; esac done
# 验证时间字段合法性 if [ "$TIME_FIELD" != "request_time" ] && [ "$TIME_FIELD" != "upstream_response_time" ]; then echo "错误: 时间字段必须是 request_time 或 upstream_response_time" exit 1 fi
# 确定时间字段在日志中的列数(根据实际log_format调整) # 以下假设为默认combined日志格式扩展,包含upstream_response_time # 请根据实际日志格式修改字段索引 if [ "$TIME_FIELD" = "request_time" ]; then TIME_COLUMN=10 # 假设request_time在第10列 else TIME_COLUMN=15 # 假设upstream_response_time在第15列 fi
# 构建筛选条件 FILTER="" if [ -n "$DOMAIN" ]; then FILTER="$FILTER | grep '$DOMAIN'" fi
if [ -n "$STATUS_CODE" ]; then # 假设状态码在第9列(根据实际日志格式调整) FILTER="$FILTER | awk '\$9 == $STATUS_CODE {print \$0}'" fi
# 执行分析命令 echo "分析日志: $LOG_FILE" echo "筛选条件: 域名=$DOMAIN, 状态码=$STATUS_CODE, 时间字段=$TIME_FIELD, 最小耗时=$TIME_THRESHOLD秒" echo "----------------------------------------"
eval "cat $LOG_FILE $FILTER | awk -v col=$TIME_COLUMN -v threshold=$TIME_THRESHOLD ' \$col + 0 >= threshold { # 转换为数字比较,过滤小于阈值的记录 print \$col \"\t\" \$7 \"\t\" \$9 # 输出: 耗时 接口路径 状态码 } ' | sort -k1,1nr | head -n $TOP_N"
echo "----------------------------------------" echo "字段说明: [耗时(秒)] [接口路径] [状态码]"
|