场景
有时候需要对一些日志进行分组统计排序,比如统计下nginx日志昨天的QPS是多少
原理
分析文本,取出目标信息,可以用cut,在进行分组统计,可以用awk,最后排序,可以用sort
实战
nginx access日志长下面这样
192.168.1.100 - - [13/Jan/2021:00:05:11 +0800] "POST /app/images/logo.png HTTP/1.1" 200 3430 "-" "Jakarta Commons-HttpClient/3.1" "-" "0.106" "0.106" "192.168.1.105:8080"
192.168.1.100 - - [13/Jan/2021:00:05:11 +0800] "POST /app/images/logo.png HTTP/1.1" 200 3430 "-" "Jakarta Commons-HttpClient/3.1" "-" "0.106" "0.106" "192.168.1.105:8080"
分析一下:要统计QPS,只要把时间13/Jan/2021:00:05:11
取出来分组统计就可以了
取时间cut
用cut命令,-c20-39意思是从第23取到39,不知道具体是多少就要个测,前面最好加一个head -n 10
表示取首10行,否则日志太大终端直接卡死
head -n 10 access_bak_2021-01-13.log| cut -c20-39
13/Jan/2021:00:05:11
13/Jan/2021:00:05:11
13/Jan/2021:00:05:11
13/Jan/2021:00:05:14
13/Jan/2021:00:05:14
13/Jan/2021:00:05:14
13/Jan/2021:00:05:15
13/Jan/2021:00:05:15
13/Jan/2021:00:05:15
13/Jan/2021:00:05:15
分组统计awk
a[$1]+=1
表示对第一列而言,遇到一样的就加一个1,反正对于只有一列的分组统计来说直接加后面这一坨就对了:awk '{a[$1]+=1}END{for (i in a)print i,a[i]}'
head -n 10 access_bak_2021-01-13.log| cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}'
13/Jan/2021:00:05:11 3
13/Jan/2021:00:05:14 3
13/Jan/2021:00:05:15 4
到这里其实统计效果已经出来了
排序sort
sort命令中
-
-n
表示以数值计算,否则sort会认为2比10大,因为2比1大嘛,这是sort的一贯作风 -
-r
表示逆序,不加表示顺序 -
-k2
表示以第2列来排序
当然你也可以写成-nrk2
,所以最后就是下面这种效果
head -n 10 access_bak_2021-01-13.log| cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}' | sort -n -r -k2
13/Jan/2021:00:05:15 4
13/Jan/2021:00:05:14 3
13/Jan/2021:00:05:11 3
后记
实际中可能是这样的,后面加个| more
当数据太多的时候使用
cat access_bak_2021-01-13.log| cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}' | sort -n -r -k2 | more
也可能是这样的,最前面加一个grep
用于最基本的筛选,比如你的nginx中多个应用或者你仅仅想统计某个path的时候
grep 'app' access_bak_2021-01-13.log| cut -c20-39 | awk '{a[$1]+=1}END{for (i in a)print i,a[i]}' | sort -n -r -k2 | more