先看下结论,然后再说背景吧~~
目录
结论
统计pv :
cat access.log | grep '接口' | wc -l
#例
cat access.log | grep '/test/index/index' | wc -l
统计单个接口平均耗时
cat access.log | grep 'test/index/index' | awk '{print $(NF-11)}' | awk '{cost+=$1;pv++;}END {printf("pv=%d totalCost=%s avgCost=%s\n", pv, cost, cost/pv)}'
背景
最近线上接口频繁出现超时,需要对接口耗时做个分析。分析:超时pv占比;接口平均耗时。
本人主要是php研发,可以通过php脚本进行统计,之前听过一位大佬说,不再是新人之后,怎么才能让自己感觉到成长了呢,就是采用不同的方式解决同一个问题。于是想直接通过linux命令的方式统计,两方面原因:一方面是采用命令方式只需要简单写几行命令即可 提高效率,当遇到线上问题时,可以迅速通过日志分析定位问题; 另一方面是可以提升一下linux命令的使用,拓宽知识面。
命令分析
统计单个接口平均耗时
cat access.log | grep 'test/index/index' | awk '{print $(NF-11)}' | awk '{cost+=$1;pv++;}END {printf("pv=%d totalCost=%s avgCost=%s\n", pv, cost, cost/pv)}'
其中:
1.
awk '{print $(NF-11)}'
access 日志的格式在nginx.conf 的log_format里有固定格式,以我们的日志格式为例进行分析,我们的log_format如下,xxx代表某种日志。
'$remote_addr - "xxx" "xxx" "$request" '
'"xxx" "xxx" "$http_cookie" "$http_user_agent" '
'$request_time xxx xxx xxx xxx $host '
'xxx xxx xxx xxx xxx';
按照空格分隔$request_time所在的位置是正数第11个位置也巧了也位于倒数第11个位置,为什么采用倒数第11个位置呢而不是正数第11个位置呢。三个原因:
1)在 $request_time之前有个$http_cookie,$http_user_agent,这些都是根据不同的登录途径、不同的客户端会有不同的信息会包含不确定空格,这样就导致我们用空格分隔不能确定 $request_time的位置
2)有人会问不能确定$request_time的位置,采用grep呢,答案不行。因为统计的是耗时,无法grep, 再者$request_time前后无固定关键词。
3)既然以上两个方法不能确定,那就从后往前看,后面的日志信息都是固定的,这样就可以确定位置了。
2.
awk '{cost+=$1;pv++;}END {printf("pv=%d totalCost=%s avgCost=%s\n", pv, cost, cost/pv)}'
cost+=$1 对耗时进行相加,pv++ 统计pv, 命令结束后加个END标识要执行的命令结束了,后面printf是要输出了。
printf对输出进行格式化,与php、java中的printf类似。
画蛇添足
统计命令为了不用每次使用重新敲一遍,写了个shell脚本,对变量的理解开始不对竟然这样写的
cat access.log | grep 'test/index/index' | awk '{print $(NF-11)}' | awk '{cost+=$1;pv++;}END {printf("pv=%d totalCost=%s avgCost=%s\n", ${pv}, ${cost}, ${cost}/${pv})}'
结果总是空,就原子性测试,cat /home/homework/clog/webserver/access.log | grep 'test/index/index' | awk '{print $(NF-11)}' 这个结果是正常的,但是整体就不行,为啥呢?
想到是在awk里加了$的原因吗,去掉执行以下,好了~~~~
嗯!
linux初学者,发现有问题可以留言哦,我会及时改正的~~