2014-01-14 129 views
0

我不是在脚本很好结合的awk脚本..为Apache日志

我有两个剧本,第一个是提取我的访问日志的最后五分钟,而第二个是计算apache响应时间的标准偏差,所以我可以创建一个nagios警报。

所以,基本上我需要的是计算Apache的access_log的最后五分钟的标准偏差。

任何人都可以帮我一下吗?

脚本一个

x=$((5*60)) 
last=$(tail -n1 access_log|awk -F'[][]' '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%s -d \""$2"\""|getline d; print d;}') 

awk -F'[][]' -v last=$last -v x=$x '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%s -d \""$2"\""|getline d; if (last-d<=x)print $0 }' 

脚本2

awk '{x[NR]=$11; s+=$11} END{a=s/NR; for (i in x){ss += (x[i]-a)^2} sd = sqrt(ss/NR); print "SD = "sd}' access_log 

哎呀,我已经想通了,问题是第二个脚本实际上解析错行,所以我的连接提前

正确的脚本

# this variable you could customize, important is convert to seconds. 
# e.g 5days=$((5*24*3600)) 
x=$((5*60)) #here we take 5 mins as example 

# this line get the timestamp in seconds of last line of your logfile 
last=$(tail -n1 access_log2|awk -F'[][]' '{ gsub(/\//," ",$2); sub(/:/," ",$2);   "date +%s -d \""$2"\""|getline d; print d;}') 


awk -F'[][]' -v last=$last -v x=$x '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%s -d \""$2"\""|getline d; if (last-d<=x)print $0 }' access_log2 | 
awk '{x[NR]=$14; s+=$14} END{a=s/NR; for (i in x){ss += (x[i]-a)^2} sd = sqrt(ss/NR); print "SD = "sd}' 

谢谢

+2

可不可以给一些样品输入或日志,以及关于你在哪里有点解释卡住? – fedorqui

+1

请注意,在第二个脚本中,您将每个响应时间存储在一个数组中,因此您可以获得一个潜在的巨大数组。你可以通过存储时间平方的运行总和来避免这种情况,并用平均数的平方来做一些简单的数学运算。 –

+0

顺便说一下,我认为你的第二个脚本适用于我(平均文件大小,导致我的日志不打印响应时间) –

回答

1

避免获得EPOC时间,这里是我的建议,以简化您的问题。

首先,获得5分钟的时间与以下格式之前:

MIN=$(date -d "-5 minutes" +%Y%m%d%H%M%S) 

例如,输出的时间会是这样的:20140114023124

可以5天前设置,或其他时间,随你喜欢。

然后在awk或其他格式中重新设置access_log [14/Jan/2014:02:36:50 +0100]的时间部分,您应该得到20140114023650并与$ MIN比较,如果超过$ MIN,则将其打印出来。

因此,脚本将(导出5分钟内生成的日志)。

MIN=$(date -d "-5 minutes" +%Y%m%d%H%M%S) 
awk -F'[][]' -v m=$MIN '{ gsub(/\//," ",$2); sub(/:/," ",$2); "date +%Y%m%d%H%M%S -d \""$2"\""|getline d; if (d>=m) print }' access_log 

您可以将标准偏差计算为awk命令,或者只是导出到存在代码:awk '{x[NR]=$14; s+=$14} END{a=s/NR; for (i in x){ss += (x[i]-a)^2} sd = sqrt(ss/NR); print "SD = "sd}'