用awk统计nginx日志一段时间内访问最高的ip
本文主要分析nginx的access.log日志,统计半小时、1个小时、1天内访问量最高的ip。
log_format日志格式
以下为nginx日志格式,使用“ | ”分割各个变量,有利于分析。第1个变量$time_local,为日志的时间。第5个变量$remote_addr,为ip地址。
log_format main '$time_local | $status | $request_time | $upstream_response_time | $remote_addr '
'| "$request" | "$http_user_agent" | "$http_referer" | $remote_user | $body_bytes_sent | $content_length';
以下为access.log的日志样例。
23/Dec/2019:15:15:11 +0800 | 200 | 0.008 | 0.008 | 106.14.220.45 | "GET / HTTP/1.1" | "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:36.0) Gecko/20100101 Firefox/36.0" | "-" | - | 4647 | -
23/Dec/2019:15:15:38 +0800 | 200 | 0.012 | 0.012 | 113.74.157.161 | "GET / HTTP/1.1" | "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" | "-" | - | 4647 | -
解析日志
以下代码需要在linux环境下运行:先用awk命令,对日志进行分析,分析结果用sort命令、uniq命令排序、统计,head命令输出前几个记录。
以下为 ip.sh 的完整代码。
#!/bin/bash
# access.log文件的路径
file="/var/log/nginx/access.log"
let startLogTime=60*60*24
let headCount=10
# 第一个参数为开始分析日志的时间
if [[ !((-z $1)) ]]; then
let startLogTime=$1
fi
echo "startLogTime " $startLogTime
# 第二个参数显示最多的几个记录
if [[ !((-z $2)) ]]; then
let headCount=$2
fi
echo "headCount " $headCount
awk -v startLogTime="$startLogTime" '
BEGIN{
FS="|"
startTime=strftime("%d%Y%H%M%S %z", systime() - startLogTime)
}
{
now=gensub(/[a-zA-Z\/:]*/, "", "g", $1)
if (now > startTime) {
print $5
}
}
' $file | sort | uniq -c | sort -rn | head -$headCount |
while read line; do
FS=' ' read -r -a array <<< "$line"
ip="${array[1]}"
echo -e "${array[1]}\t${array[0]}"
done
运行
第1个参数是前一段时间,单位为秒,如 60*60,表示一个小时,默认是一天。
第2个参数是输出最多的几条记录,默认为10。
$ sh ip.sh 60*60 5
startLogTime 216000
headCount 5
113.74.157.161 6
66.249.69.250 4
124.78.41.86 4
66.249.69.254 2
66.249.69.252 2