linux awk nginx log,awk处理nginx日志

awk处理nginx日志

主要是将非结构化的日志处理成结构话数据并入库做统计,本场景是统计rest接口的调用情况:

nginx日志设置

awk抽取字段

awk日期格式化

拼装sql与导入数据库

crontab自动执行

配合log rotate

统计分析

邮件通知

报表展示

nginx日志设置

nginx.conf中:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'$request_time $upstream_response_time $pipe'

'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

awk

抽取字段

代码:

awk '{print substr($4,2,11),substr($4,14,15),substr($6,2),$7,$12,$13}' /var/log/nginx/access.log > ~/stat.log

# 获取访问时间,请求方法,rest url,request time和response time

日期格式化

nginx的时间是这种格式[02/Oct/2016 04:50:11],先用date格式化的方法:

awk -v A=$(date +%Y%m%d) '{gsub("/"," ",$1); sprintf("date -d \"%s %s\" \"+%%Y-%%m-%%d %%H:%%M:%%S\"", $1,$2) | getline D;printf("insert interfaceInvoke(ddate,cdate,method,url,requesttime,responsetime) values(\"%s\",\"%s\",\"%s\",\"%s\",%f,%f);\n",A,D,$3,$4,$5,$6)}' ~/stat.log > ~/stat.sql

发现经常有too many open files错误,嵌套的date命令用掉太多文件句柄,7k条测试数据执行完成需要13s。

考虑了一下,去掉gsub和date,由于时间字符串的格式是固定的、每一部分的长度也是固定的,全部使用字符串处理:

awk -v A=$(date +%Y%m%d) 'BEGIN{ mon["Jan"] = 1; mon["Feb"] = 2; mon["Mar"] = 3; mon["Apr"] = 4; mon["May"] = 5; mon["Jun"] = 6; mon["Jul"] = 7; mon["Aug"] = 8; mon["Sep"] = 9; mon["Oct"] = 10; mon["Nov"] = 11; mon["Dec"] = 12; }; {printf("insert interfaceInvoke(ddate,cdate,method,url,requesttime,responsetime) values(\"%s\",\"%s-%s-%s %s\",\"%s\",\"%s\",%f,%f);\n",A,substr($1,8,4),mon[substr($1,4,3)],substr($1,1,2),$2 ,$3,$4,$5,$6)}' ~/stat.log > ~/stat.sql

这样就不需要执行gsub替换和嵌套date命令,7k条测试执行时间只有0.026s,也可以文件句柄的问题了。

invokeStat.sh全部代码如下:

awk '{print substr($4,2,11),substr($4,14,15),substr($6,2),$7,$12,$13}' /var/log/nginx/access.log > ~/stat.log

# insert into db

awk -v A=$(date +%Y%m%d) 'BEGIN{ mon["Jan"] = 1; mon["Feb"] = 2; mon["Mar"] = 3; mon["Apr"] = 4; mon["May"] = 5; mon["Jun"] = 6; mon["Jul"] = 7; mon["Aug"] = 8; mon["Sep"] = 9; mon["Oct"] = 10; mon["Nov"] = 11; mon["Dec"] = 12; }; {printf("insert tablename(ddate,cdate,method,url,requesttime,responsetime) values(\"%s\",\"%s-%s-%s %s\",\"%s\",\"%s\",%f,%f);\n",A,substr($1,8,4),mon[substr($1,4,3)],substr($1,1,2),$2 ,$3,$4,$5,$6)}' ~/stat.log > ~/stat.sql

mysql -h192.168.*.* -uXXX -pXXX dbname < ~/stat.sql

crontab自动执行

/etc/crontab里,添加:

59 23 * * * root /soft/stat/invokeStat.sh

# 每天晚上12点前执行一次

配合log rotate

/etc/logrotate.d/nginx中:

/var/log/nginx/*.log {

daily

missingok

rotate 52

compress

delaycompress

notifempty

create 640 nginx adm

sharedscripts

postrotate

[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`

endscript

}

通过logrotate每天晚上切换一次日志,保证invokeStat.sh每天跑的都是最新的,而不是昨天的日志。其实也可以考虑这两个脚本合并成一个。invokeStat先执行。

统计分析

主要先实现调用次数统计:cat file | wc -l

调用时间大于1s的统计: awk '{$13>1 {......

调用时间大于60s的统计: awk '{$13>60 {......

调用时间最长的10次统计:sort -k3nr ...... | head -n 10

crontab自动执行

/etc/crontab里,添加:

59 23 * * * root /soft/stat/invokeStat.sh

# 每天晚上12点前执行一次

邮件通知

先配置sendmail,然后使用mail命令:

cat ~/mystat.log | mail -s "[APP]执行时间超过1s的接口统计-"$CURDATE kimmking@163.com

如果发送的文件时html类型:

cat ~/mystat.log | mail -s "$(echo -e "[APP]执行时间超过1s的接口统计-$CURDATE\nContent-Type: text/html;charset=utf-8")" kimmking@163.com

报表展示

todo list

集合echart与sql的字段组合,统计具体接口的调用情况

跟踪接口在不同时间的响应时间

优化慢请求

增量?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值