实用的nginx日志处理案例
一、涉及的知识点
vim /etc/nginx/nginx.conf(日志格式定义位置)
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
$remote_addr, 远程地址: 记录客户端IP地址
$remote_user,远程用户:记录客户端用户名称
[$time_local],本地时间:服务器自身时间
$request, 请求:记录请求的URL和HTTP协议
$status 状态:记录请求状态
$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小
$http_referer 记录从哪个页面链接访问过来的 (超链接)(referer引用)
$http_user_agent ,记录客户端浏览器相关信息
$http_x_forwarded_for,代理IP
$request_length 请求的长度(包括请求行,请求头和请求正文)
$time_iso8601 ISO8601标准格式下的本地时间。
$bytes_sent 发送给客户端的总字节数 (可在主配置文件中,增加此项观c)
$msec 日志写入时间。单位为秒,精度是毫秒。
如:访问日志: /var/log/nginx/access.log
192.168.40.1 - - [28/Aug/2019:15:49:21 +0800] "GET /zjzlinux.com HTTP/1.1" 404 153 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0" "-"
192.168.40.19(远程主机ip) - -(第一个-为分隔符,第二个为系统默认账号nobody)
[28/Aug/2019:15:49:21 +0800] 服务器时间;"GET /zjzlinux.com HTTP/1.1"request下载或上传
404 http状态码 153 。。。。。
二、实战案例
1. 统计2017年9月5日 PV量(网页页面访问量)
8点-9点间
grep '05/Sep/2017:08' sz.mobiletrain.org.log |wc -l awk '$4>="[05/Sep/2017:08:00:00" && $4<="[05/Sep/2017:09:00:00" {print $0}' sz.mobiletrain.org.log | wc -l
2. 统计2017年9月5日 一天内访问最多的10个IP(ip top10)
grep '05/Sep/2017' cd.mobiletrain.org.log | awk '{ ips[$1]++ } END{for(i in ips){print i,ips[i]} } '| sort -k2 -rn | head -n10 (end小写不显示)
3. 统计2017年9月5日 访问大于100次的IP
grep '05/Sep/2017' cd.mobiletrain.org.log | awk '{ ips[$1]++ } END{for(i in ips){ if(ips[i]>100) {print i,ips[i]}} } '| sort -k2 -rn | head -n10
4. 统计2017年9月5日 访问最多的10个页面($request top 10)
grep '05/Sep/2017' cd.mobiletrain.org.log |awk '{urls[$7]++} END{for(i in urls){print urls[i],i}}' |sort -k1 -rn |head -n10
5. 统计2017年9月5日 每个URL访问内容总大小($body_bytes_sent)
grep '05/Sep/2017' sz.mobiletrain.org.log |awk '{ urls[$7]++; size[$7]+=$10}END{for(i in urls){print urls[i],size[i],i}}'|sort -k1 -rn | head -n10
6. 统计2017年9月5日 每个IP访问状态码数量($status)
grep '05/Sep/2017' cd.mobiletrain.org.log | awk '{ ip_code[$1" "$9]++}END{ for(i in ip_code){print i,ip_code[i]} }' | sort -k1 -rn | head -n10
7. 统计2017年9月5日 每个IP访问状态码为404及出现次数($status)
grep '05/Sep/2017' cd.mobiletrain.org.log |awk '$9=="404"{ccc[$1" "$9]++}END{for(i in ccc){print i,ccc[i]}}' | sort -k3 -rn grep '05/Sep/2017' sz.mobiletrain.org.log | awk '{if($9="404"){ip_code[$1" "$9]++}}END{for(i in ip_code){print i,ip_code[i]}}'
8. 统计前一分钟的PV量
date=$(date -d '-1 minute' +%d/%b/%Y:%H:%M);awk -v date=$date '$0 ~ date {i++} END{print i}' sz.mobiletrain.org.log
shell中的变量在awk程序中无法使用,因为在执行AWK时,是一个新的进程去处理的,因此就需要-v 来向awk程序中传参数了,
你比如在shell程序中有一个变量a=15,你在awk程序中直接使用变量a是不行的,而你用awk -v b=a, 这样在AWK程序中就可以使用变量b了!也就相当于使用a了!
# date=$(date -d '-1 minute' +%Y:%H:%M); awk -v date=$date '$0 ~ date{i++}END{print i}' /var/log/nginx/xuleilinux.access.log
9. 统计2017年9月5日 8:30-9:00,每个IP,出现404状态码的数量
awk '$4>="[05/Sep/2017:08:30:00" && $4<="[05/Sep/2017:09:00:00" {if($9="404"){ip_code[$1" "$9]++}} END{for(i in ip_code){print i,ip_code[i]}}' sz.mobiletrain.org.log
10. 统计2017年9月5日 各种状态码数量
grep '05/Sep/2017' sz.mobiletrain.org.log | awk '{code[$9]++} END{for(i in code){print i,code[i]}}'
百分比
grep '05/Sep/2017' sz.mobiletrain.org.log | awk '{code[$9]++;total++} END{for(i in code){printf i" ";printf code[i]"\t";printf "%.2f",code[i]/total*100;print "%"}}'