awk分析日誌獲得響應時間的最大最小和平均值

今天有個分析日誌的需求,要得到指定的幾個請求的響應時間的最大值,最小值和平均值android

從nginx配置中找到日誌的格式以下:ios

log_format _main '$remote_addr "$time_iso8601" $request_method "$uri" "$args" "$request_body" $status $body_bytes_sent $request_time "$http_user_agent"';

倒數第二項$request_time即爲響應時間nginx

實際日誌截取部分以下,域名換掉了:shell

10.100.27.171 "2015-08-01T00:00:02+08:00" GET "/interface/ipad_v3/sub_channels" "cid=85&ver=3.9.5" "-" 200 588 0.003 "api.3g.example.com/3.0"
10.100.27.172 "2015-08-01T00:00:02+08:00" GET "/interface/ios_v3/sub_channel_details_with_playlist" "sub_channel_id=227&ver=3.9" "-" 200 2912 0.334 "api.3g.example.com/3.0"
10.100.27.172 "2015-08-01T00:00:02+08:00" GET "/interface/android_v3/sub_channel_details" "sub_channel_id=107&show_game_information=1&ver=4.8" "-" 200 3480 0.129 "api.3g.example.com/3.0"api

日誌文件名格式大概是log.20150801這樣的,我打算把腳本和日誌放一個文件夾下
一開始函數是這麼寫的,須要注意的是,$1既能表示shell函數的第一個參數,又能表示awk中的第一個域,有衝突。因此用'"$1"',用'將前面的句子關閉,而後在""中插入shell的參數$1,再用'開啓後面的句子;也能夠用awk -v needle="$1"這種賦值替換方式bash

#! /bin/bash

function get_min(){
        ls | grep 'log.' | xargs cat | awk '$7==200 && $4 ~/^"'"$1"'/{print "Min = ", $9}' | sort -n -k 2  |   head -1
}

function get_max() {
        ls | grep 'log.' | xargs cat | awk '$7==200 && $4 ~/^"'"$1"'/{print "Max = ", $9}' | sort -rn -k 2  |   head -1
}

function get_avg() {
        ls | grep 'log.' | xargs cat | awk '$7==200 && $4 ~/^"'"$1"'/{sum+=$9} END {print "Average = ", sum/NR}'
}

最容易想到的,明顯不是最優的,代碼很冗餘。將文件遍歷一次,最大最小和平均均可以計算出來的,再不濟,最大值和最小值其實在排序以後就出來了,能夠這樣用sed輸出兩條記錄函數

awkfunction get_min_and max {
    ls | grep 'log.' | xargs cat | awk '$8=200 && $4 ~/^"'"$1"'/{print $9}' | sort -n -k 2  |   sed -n '1p;$p'
}

仔細研究了下awk,最後的代碼是這樣的日誌

awk#! /bin/bash

function cal_work(){
        ls | grep 'log.' | xargs cat | awk   'BEGIN{max=0;min=1}
                {if ($4 ~ /^"'"$1"'/  && $(NF-3)==200){
                        sum+=$9; count+=1;
                        if($9 > max) max=$9 fi;if($9 < min) min=$9 fi;
                    }
                }
                END {print "Average = ", sum/count;print "Max = ", max;print "Min", min}'
}

function get_stat(){
        target=$1
        target=${target//\//\\/}
        cal_work $target
}

get_stat '/interface/ipad_v3/sub_channels'

要查詢的path中有斜槓,斜槓前要加'\'轉義,這一步在get_stat中進行code

相關文章
相關標籤/搜索