zoukankan      html  css  js  c++  java
  • 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/"
    
    #生成日志文件存放目录
    log_path="/var/log/nginx/"
    #设置pid文件
    nginx_pid_path="/run/nginx.pid"
    
    #定义日期
    yesterday=`date -d "yesterday" +"%Y%m%d"`
    mkdir -p ${before_log}${yesterday} 
    
    #重命名访问日志文件
    mv ${log_path}access.log ${before_log}${yesterday}/access_admin.log
    
    #重命名错误日志文件
    mv ${log_path}error.log ${before_log}${yesterday}/error_admin.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
    ", requests[s],s)}}' | sort -nr | head -n 10

    iii.nginx处理请求的时间

    每分钟nginx处理请求的平均时间,zabbix每分钟检测一次 

    复制代码
    DATE=/bin/date
    one_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=0
    for i in `echo $all_times`
    do
        sum=$(echo "$sum + $i" | bc)
    done
    ding=0.0
    if [ $(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
    ", 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
    ",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
    ", 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
     总结:下面是监控脚本,脚本中图片带宽,访问ip次数没有再脚本中显示,在日志分析中后续会更新...(注:该脚本仅供在zabbix直接使用,nagios还需要在脚本里定义报警级别与阀值)
    复制代码
      1 #!/bin/bash
      2 export PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
      3 PROGNAME=`basename $0`
      4 REVISION="2.0"
      5 
      6 
      7 print_usage() {
      8     echo "Usage:"
      9     echo "      $PROGNAME -a act_conn" 
     10     echo "      $PROGNAME -d discard" 
     11     echo "      $PROGNAME -r all_request" 
     12     echo "      $PROGNAME -t time_request -l log" 
     13     echo "      $PROGNAME -s request_reqs -l log" 
     14     echo "      $PROGNAME -c check_spi -l log" 
     15     echo "      $PROGNAME -all get_all -l log" 
     16     echo "      $PROGNAME -g get_count -l log -p port" 
     17     echo "      $PROGNAME -f fail_return -l log -n number" 
     18     echo "      $PROGNAME --help|-h"
     19     echo "      $PROGNAME --version|-v"
     20 }
     21 
     22 
     23 if [ $# -lt 1 ]; then
     24     print_usage
     25     exit $STATE_UNKNOWN
     26 fi
     27 
     28 # Grab the command line arguments
     29 while test -n "$1"; do
     30     case "$1" in
     31         --help)
     32             print_usage
     33             exit $STATE_UNKNOWN
     34             ;;
     35         -h)
     36             print_usage
     37             exit $STATE_UNKNOWN
     38             ;;
     39         --version)
     40             echo "$PROGNAME $REVISION"
     41             exit $STATE_UNKNOWN
     42             ;;
     43         -V)
     44             echo "$PROGNAME $REVISION"
     45             exit $STATE_UNKNOWN
     46             ;;
     47     -a)
     48             act_conn=$2
     49             shift
     50             ;;
     51     -H)
     52             host=$2
     53             shift
     54             ;;
     55     -d)
     56             discard=$2
     57             shift
     58             ;;
     59     -r)
     60             all_request=$2
     61             shift
     62             ;;
     63         -t)
     64             time_request=$2
     65             shift
     66             ;;
     67         -l)
     68             log=$2
     69             shift
     70             ;;
     71         -f)
     72             fail_return=$2
     73             shift
     74             ;;
     75         -n)
     76             number=$2
     77             shift
     78             ;;
     79         -s)
     80             request_reqs=$2
     81             shift
     82             ;;
     83         -c)
     84             check_spi=$2
     85             shift
     86             ;;
     87         -all)
     88             get_all=$2
     89             shift
     90             ;;
     91         -g)
     92             get_count=$2
     93             shift
     94             ;;
     95         -p)
     96             port=$2
     97             shift
     98             ;;
     99     *)
    100             echo "Unknown argument: $1"
    101             print_usage
    102             exit $STATE_UNKNOWN
    103             ;;
    104     esac
    105     shift
    106 done
    107 #获取前一分钟的标志
    108 get_last_minute()
    109 {
    110 DATE=/bin/date
    111 time=`$DATE -d last-minute +%d/%m/%Y:%H:%M | awk -F "/" '{print $1,$3}'`
    112 echo $time
    113 }
    114 
    115 #每分钟活跃的连接数
    116 act_conn()
    117 {
    118 active_connection=`curl -s http://127.0.0.1/ngx_status| grep connection | awk -F ":" '{print $2}'`
    119 echo $active_connection
    120 }
    121 $act_conn
    122 
    123 #是否有丢弃的连接数,为0是一个也没有丢弃
    124 discard()
    125 {
    126 accepts_handled=`curl -s http://127.0.0.1/ngx_status| awk '$1~/^s/ {for (i=1;i<=2;i++) {print;getline}}' |awk '{print $1,$2,$3}' | grep -v server`
    127 accepts=`echo $accepts_handled | awk '{print $1}'`
    128 handled=`echo $accepts_handled | awk '{print $2}'`
    129 echo `expr $accepts - $handled`
    130 }
    131 $discard
    132 
    133 #每分钟的总请求数,zabbix上需要配置减法哦!!
    134 all_request()
    135 {
    136 all_requests=`curl -s http://127.0.0.1/ngx_status| awk '$1~/^s/ {for (i=1;i<=2;i++) {print;getline}}' |awk '{print $1,$2,$3}' | grep -v server | awk '{print $3}'`
    137 echo $all_requests
    138 }
    139 $all_request
    140 
    141 #处理请求的时间
    142 time_request()
    143 {
    144 result=`get_last_minute`
    145 day=`echo $result | awk '{print $1}'`
    146 hour=`echo $result | awk '{print $2}'`
    147 all_times=`cat $log | grep $day | grep $hour | awk '{print $11}'`
    148 all_number=`cat $log | grep $day | grep $hour | awk '{print $11}'| wc -l`
    149 sum=0
    150 for i in `echo $all_times`
    151 do
    152     sum=$(echo "$sum + $i" | bc)
    153 done
    154 if [ $sum == 0 ];then
    155     echo $sum
    156 else
    157     every_num=`gawk -v x=$sum -v y=$all_number 'BEGIN{printf x/y}'`
    158     echo $every_num
    159 fi
    160 }
    161 $time_request
    162 
    163 #日志文件中出现4xx,5xx的错误
    164 fail_return()
    165 {
    166 result=`get_last_minute`
    167 day=`echo $result | awk '{print $1}'`
    168 hour=`echo $result | awk '{print $2}'`
    169 fail_code=`cat $log | grep $day | grep $hour | awk '{print $9}' | grep "$number[0-9][0-9]" | wc -l`
    170 echo $fail_code
    171 }
    172 $fail_return
    173 
    174 #平均每秒的请求数
    175 request_reqs()
    176 {
    177 result=`get_last_minute`
    178 day=`echo $result | awk '{print $1}'`
    179 hour=`echo $result | awk '{print $2}'`
    180 req_num=`cat $log | grep $day |grep $hour | awk '{sec=substr($4,2,20);reqs++;reqsBySec[sec]++;} END{print reqs/length(reqsBySec)}'`
    181 echo $req_num
    182 }
    183 $request_reqs
    184 
    185 #监控是否被爬虫了,zabbix配置触发器的时候只要不等于0就报警
    186 check_spi()
    187 {
    188 result=`get_last_minute`
    189 day=`echo $result | awk '{print $1}'`
    190 hour=`echo $result | awk '{print $2}'`
    191 spi=`cat $log |grep $day |grep $hour | egrep 'spider|bot' |awk '{name=$17;if(index($15,"spider")>0){name=$15};spiders[name]++} END{for(name in spiders) {printf("%s %s
    ",spiders[name], name)}}' | wc -l`
    192 echo $spi
    193 }
    194 $check_spi
    195 
    196 #每分钟用户的访问到了那里?
    197 get_count()
    198 {
    199 result=`get_last_minute`
    200 day=`echo $result | awk '{print $1}'`
    201 hour=`echo $result | awk '{print $2}'`
    202 Arrive=`cat $log | grep $day | grep $hour | 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
    ",server, count[server])}}'| grep $port`
    203 echo $Arrive | awk '{print $2}'
    204 }
    205 $get_count
    206 
    207 #每分钟的用户访问总数
    208 get_all()
    209 {
    210 result=`get_last_minute`
    211 day=`echo $result | awk '{print $1}'`
    212 hour=`echo $result | awk '{print $2}'`
    213 Arrive=`cat $log | grep $day | grep $hour | awk '{upServer=$13;upTime=$12;if(upServer == "-"){upServer="Nginx"};if(upTime == "-"){upTime=0};upTimes[upServer]+=upTime;count[upServer]++;totalCount++;} END{for(server in upTimes){print totalCount}}'`
    214 echo $Arrive  |awk '{print $1}'
    215 }
    216 $get_all
    复制代码

    转自

    nginx监控 - 迎领启航 - 博客园 https://www.cnblogs.com/ylqh/p/5885465.html

    Nginx 日志中的金矿 https://www.toutiao.com/a6640001649387504135/?tt_from=mobile_qq&utm_campaign=client_share&timestamp=1546050181&app=news_article&utm_source=mobile_qq&iid=26112390770&utm_medium=toutiao_ios&group_id=6640001649387504135

  • 相关阅读:
    BAPI LIST
    如何设计折叠屏幕
    图形学习 Javascript 正则 regexper.com
    Javascript 的数据是什么数据类型?
    Javascript 严格模式下不允许删除一个不允许删除的属性
    Javascript 在严格模式下禁止指向 this
    指针自增学习
    Javascript 严格模式下几个禁忌
    笔记本设置 2K 显示屏 Intel HD Graphics 3000
    Javascript 在严格模式下不允许删除变量或对象
  • 原文地址:https://www.cnblogs.com/paul8339/p/10233247.html
Copyright © 2011-2022 走看看