首页 > 代码库 > nginx监控
nginx监控
nginx监控
第一:nginx的基础监控:
1.进程监控
2.端口监控
在这里nginx的基础监控就不详细说了,注意的是:这两个是必须要加的。并且对于zabbix而言的话,一定要加上触发器的。有问题必须报警。
第二:nginx的特殊监控:
1.利用nginx的stub_status模块监控:
location /ngn_status { stub_status on; access_log off; }
(1)nginx的每分钟的总请求数
curl -s http://127.0.0.1/ngn_status| grep connection | awk -F ":" ‘{print $2}‘
(2)nginx的活跃数的链接数
accepts_handled=`curl -s http://127.0.0.1/ngn_status| awk ‘$1~/^s/ {for (i=1;i<=2;i++) {print;getline}}‘ |awk ‘{print $1,$2,$3}‘ | grep -v server`accepts=`echo $accepts_handled | awk ‘{print $1}‘`handled=`echo $accepts_handled | awk ‘{print $2}‘`echo `expr $accepts - $handled`
(3)nginx的丢弃数连接数
#每分钟的总请求数,zabbix上需要配置减法哦!!all_requests=`curl -s http://127.0.0.1/ngn_status| awk ‘$1~/^s/ {for (i=1;i<=2;i++) {print;getline}}‘ |awk ‘{print $1,$2,$3}‘ | grep -v server | awk ‘{print $3}‘`echo $all_requests
2.日志监控
(1):nginx的日志监控前提:
i.规范nginx的格式,规范日志格式。这是很多团队容易忽略的地方,有时候多一个空格会让日志分析的复杂度大为增加。
nginx的日志格式:
log_format main ‘$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent $request_time $upstream_response_time $upstream_addr "$http_referer" "$http_user_agent" "$http_x_forwarded_for"‘;
详解: $remote_addr 记录客户端的ip地址,如有代理会记录代理的ip地址
$remote_user 记录客户端用户名称 [$time_local] 来访时间 "$request" 记录请求的url与http协议 $status 记录请求状态 $body_bytes_sent 记录发送给客户端文件主题的大小, 这一个可以用于监控某个文件,图片占用多大的带宽 $request_time 整个请求的总时间 $upstream_response_time 请求过程中upstream响应的时间 $upstream_addr 真正提供服务的ip地址 "$http_referer" 用来记录从那个页面链接访问过来的 "$http_user_agent" 记录客户端浏览器的相关信息 "$http_x_forwarded_for"‘; 记录客户端访问的真实ip地址
这里特别解释一下 :remote_addr与http_x_forwarded_for
remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问
这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。正如上面所述,当你使用了代理时,web服务器就不知道你的真实IP了,为了避免这个情况,代理服务器通常会增加一个叫做x_forwarded_for的头信息,把连接它的客户端IP(即你的
上网机器IP)加到这个头信息里,这样就能保证网站的web服务器能获取到真实IP
ii.nginx做日志切割,如果nginx没有做日志切割的话,会很大,造成监控误报的情况
nginx的日志切割有很多种方式方法,例如:利用系统自带的logrotate切割nginx日志,按天shell+crontab来切。
我用的是shell+crontab,
脚本:
#!/bin/bash#nginx日志切割脚本#设置备份日志文件存放目录before_log="/var/log/nginx/before_log/"#生成日志文件存放目录admin_log_path="/var/log/nginx/game_admin/"game_new_log_path="/var/log/nginx/game_new/"game_wap_new_log_path="/var/log/nginx/game_wap_new/"kf_log_path="/var/log/nginx/kf/"nginx_master_log_path="/var/log/nginx/nginx_master/"wap_wsds_log_path="/var/log/nginx/wap_wsds/"wsds_log_path="/var/log/nginx/wsds/"#设置pid文件nginx_pid_path="/run/nginx.pid"#定义日期yesterday=`date -d "yesterday" +"%Y%m%d"`mkdir -p ${before_log}${yesterday} #重命名访问日志文件mv ${admin_log_path}access.log ${before_log}${yesterday}/access_admin.logmv ${game_new_log_path}access.log ${before_log}${yesterday}/access_game_new.logmv ${game_wap_new_log_path}access.log ${before_log}${yesterday}/access_game_wap_new.logmv ${kf_log_path}access.log ${before_log}${yesterday}/access_kf.logmv ${nginx_master_log_path}access.log ${before_log}${yesterday}/access_nginx_master.logmv ${wap_wsds_log_path}access.log ${before_log}${yesterday}/access_wap_wsds.logmv ${wsds_log_path}access.log ${before_log}${yesterday}/access_wsds.log#重命名错误日志文件mv ${admin_log_path}error.log ${before_log}${yesterday}/error_admin.logmv ${game_new_log_path}error.log ${before_log}${yesterday}/error_game_new.logmv ${game_wap_new_log_path}error.log ${before_log}${yesterday}/error_game_wap_new.logmv ${kf_log_path}error.log ${before_log}${yesterday}/error_kf.logmv ${nginx_master_log_path}error.log ${before_log}${yesterday}/error_nginx_master.logmv ${wap_wsds_log_path}error.log ${before_log}${yesterday}/error_wap_wsds.logmv ${wsds_log_path}error.log ${before_log}${yesterday}/error_wsds.log#向nginx主进程发信号重新打开日志kill -USR1 `cat ${nginx_pid_path}`
结合crontab每天的0点0分执行该脚本:
00 00 * * * root /bin/bash /opt/script/cut_nginx_log.sh
(2)nginx的日志监控:
i.nginx平均每秒处理的请求数
cat main.log | awk ‘{sec=substr($4,2,20);reqs++;reqsBySec[sec]++;} END{print reqs/length(reqsBySec)}‘
ii.nginx的请求在哪一个时间是峰值,以级峰值大小(这个如果日志分析中有的话,就不需要加监控了)
cat main.log | awk ‘{sec=substr($4,2,20);requests[sec]++;} END{for(s in requests){printf("%s %s\n", requests[s],s)}}‘ | sort -nr | head -n 10
iii.nginx处理请求的时间
每分钟nginx处理请求的平均时间,zabbix每分钟检测一次
DATE=/bin/dateone_minute_ago=`$DATE -d "1 minute ago" | awk ‘{print $4}‘ | awk ‘{sub(/...$/,"")}1‘`all_times=`cat $log | grep $one_minute_ago | awk -F ‘"‘ ‘{print $13}‘ | awk ‘{print $1}‘`all_number=`cat $log | grep $one_minute_ago | awk -F ‘"‘ ‘{print $13}‘ | awk ‘{print $1}‘ | wc -l`sum=0for i in `echo $all_times`do sum=$(echo "$sum + $i" | bc)doneding=0.0if [ $(echo "$sum == $ding"|bc) -eq 1 ];then echo "sum" else every_num=`gawk -v x=$sum -v y=$all_number ‘BEGIN{printf x/y}‘` echo $every_num fi
iv.nginx的请求去访问哪里了??
less main.log | grep 15:59 | awk ‘{upServer=$13;upTime=$12;if(upServer == "-"){upServer="Nginx"};if(upTime == "-"){upTime=0};upTimes[upServer]+=upTime;count[upServer]++;totalCount++;} END{for(server in upTimes){printf("%s %s%s %ss %s\n", count[server], count[server]/totalCount *100, "%", upTimes[server]/count[server], server)}}‘
v.nginx的日志中是否有被爬虫的痕迹
cat main.log | egrep ‘spider|bot‘ | awk ‘{name=$17;if(index($15,"spider")>0){name=$15};spiders[name]++} END{for(name in spiders) {printf("%s %s\n",spiders[name], name)}}‘ | sort -nr
vi.nginx中出现次数最多的真实ip次数(可以根据实际情况,将xx分钟的大于xx的次数的ip地址找出来)
awk ‘{print $NF}‘ main.log | sort -n |uniq -c | sort -nr
vii.nginx中日志的图片占用的带宽大小,以及图片被xx分钟被访问的次数超过xx次进行报警(根据情况扩展)
cat main.log |awk ‘{url=$7; requests[url]++;bytes[url]+=$10} END{for(url in requests){printf("%sKB/req %s %s\n", bytes[url] /requests[url] / 1024, requests[url], url)}}‘ | sort -nr
viii.nginx的日志中出现4xx,5xx监控(同样可扩展)(注意:4xx,5xx同时可用这个,写监控脚本的时候用传参的方式哦)
cat main.log | awk ‘{print $9}‘ | grep 4[0-9][0-9] | wc -l
nginx监控