开心六月综合激情婷婷|欧美精品成人动漫二区|国产中文字幕综合色|亚洲人在线成视频

    1. 
      
        <b id="zqfy3"><legend id="zqfy3"><fieldset id="zqfy3"></fieldset></legend></b>
          <ul id="zqfy3"></ul>
          <blockquote id="zqfy3"><strong id="zqfy3"><dfn id="zqfy3"></dfn></strong></blockquote>
          <blockquote id="zqfy3"><legend id="zqfy3"></legend></blockquote>
          打開APP
          userphoto
          未登錄

          開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

          開通VIP
          Shell腳本實(shí)現(xiàn)Linux錯(cuò)誤日志監(jiān)控告警

          https://trainoozhou.github.io/2018/09/05/use-linux-shell-monitor-error-log/

          前文有講到,最近部署了一個(gè)服務(wù)
          但是老是被惡意的掃描
          雖然利用nginx禁止了些IP
          但我還是想在被惡意掃描時(shí)候收到一個(gè)通知信息
          讓我能知道我的服務(wù)器又被訪問了
          于是乎,就有了這篇文章

          此文目的是為了記錄自己的操作步驟
          既給自己一個(gè)復(fù)習(xí)的機(jī)會(huì),同時(shí)也能服務(wù)看到此文的讀者
          好了,話不多說
          接下來開始正文內(nèi)容


          整體的思路如下:

          1. 既然是監(jiān)控,比較方便的方式就是利用Linux的cron定時(shí)任務(wù)來定時(shí)去執(zhí)行一個(gè)操作
          2. 既然是要能被定時(shí)任務(wù)執(zhí)行的操作,那么我們就需要寫一個(gè)shell腳本
          3. shell腳本需要做什么呢?我們可以去匹配某個(gè)時(shí)間段,在時(shí)間段內(nèi)是否有新的內(nèi)容添加進(jìn)去(日志文件肯定有記錄時(shí)間的),如果有的話,則把這段內(nèi)容單獨(dú)取出來,并發(fā)送郵件通知
          4. 上面又涉及到了發(fā)郵件,發(fā)郵件比較好的方式是寫個(gè)Python腳本(因?yàn)槲业姆?wù)器自帶了python環(huán)境,而且python運(yùn)行起來也簡單)
          5. 所以,總結(jié)下來我們需要兩個(gè)文件(假定都存放在/opt/mysh/目錄):一個(gè)是可執(zhí)行的shell腳本;一個(gè)是發(fā)郵件的python腳本文件。并設(shè)定一個(gè)cron定時(shí)任務(wù)。
          接下來就是開始寫個(gè)shell腳本,如下(文件名:monitor_nginx_log.sh):
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          #!/bin/bash
          #日志文件路徑
          logfile=/var/log/nginx

          #當(dāng)天日期,年月日
          cur_date=`date +"%Y/%m/%d"`

          #開始時(shí)間(3分鐘前),時(shí)分秒
          start_time=`date -d"3 minutes ago" +"%H:%M:%S"`

          #結(jié)束時(shí)間,時(shí)分秒
          stop_time=`date +"%H:%M:%S"`

          #把新增的錯(cuò)誤日志寫到new_error_log中
          tac $logfile/error.log | awk -v st="$start_time" -v et="$stop_time" -v dt="$cur_date" '{t=$2;t1=$1; if(dt==t1 && t>=st && t<=et) {print $0}}' > $logfile/new_error_log.txt

          file_size=`du $logfile/new_error_log.txt | awk '{print $1}'`

          #new_error_log文件大小不為0,發(fā)送郵件通知
          if [[ $file_size -gt 0 ]];then
          echo `date +'%Y/%m/%d %H:%M:%S'`" there are new errors in nginx error.log" | cat >> /opt/mysh/monitor.log
          /usr/bin/python2.7 /opt/mysh/send_mail.py | tee -a /opt/mysh/monitor.log
          fi

          ps: 上面的腳本有好幾個(gè)命令,如果有疑問的話,請(qǐng)往下看,會(huì)有解釋的

          然后呢,我們還要有一個(gè)郵件發(fā)送腳本(send_mail.py),如下:
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          # -*- coding: utf-8 -*-
          import os
          import smtplib
          from email.header import Header
          from email.mime.application import MIMEApplication
          from email.mime.multipart import MIMEMultipart
          from email.mime.text import MIMEText
          from email.utils import parseaddr, formataddr

          def _format_addr(s):
          name, addr = parseaddr(s)
          return formataddr((Header(name, 'utf-8').encode(), addr))

          # 郵箱定義
          smtp_server = 'smtp.163.com'
          smtp_port = 25
          from_addr = 'from_addr@163.com'
          password = os.environ.get('MAIL_PASSWD')
          to_addr = 'to_addr@163.com'

          # 郵件對(duì)象
          msg = MIMEMultipart()
          msg['From'] = _format_addr('發(fā)件人 <%s>' % from_addr)
          msg['To'] = _format_addr('收件人 <%s>' % to_addr)
          msg['Subject'] = Header('【Support】發(fā)現(xiàn)錯(cuò)誤', 'utf-8').encode()

          # 郵件正文是MIMEText:
          html = "<html><body><h4>檢測有錯(cuò)誤發(fā)生,詳情見附件!</h4></body></html>"
          msg.attach(MIMEText(html, 'html', 'utf-8'))

          # 添加附件
          file_path = "/var/log/nginx/new_error_log.txt"
          attachment = MIMEApplication(open(r'file_path', 'rb').read())
          attachment.add_header('Content-Disposition', 'attachment', filename="new_error_log.txt")
          msg.attach(attachment)

          # 發(fā)送郵件
          print('開始發(fā)送郵件>>>')
          try:
          server = smtplib.SMTP(smtp_server, smtp_port)
          server.login(from_addr, password)
          server.sendmail(from_addr, to_addr, msg.as_string())
          server.quit()
          except Exception, e:
          print "郵件發(fā)送異常:" + e
          finally:
          print('結(jié)束郵件發(fā)送<<<')

          ps1: 上面的代碼中使用了os.environ.get('MAIL_PASSWD')獲取環(huán)境變量,可以使用export MAIL_PASS=xxxx進(jìn)行設(shè)置(只對(duì)當(dāng)前shell有效,需要永久生效請(qǐng)修改/etc/profile)

          ps2: 163的郵箱老是會(huì)退信,因?yàn)榘l(fā)送的次數(shù)多,而且內(nèi)容相似,會(huì)被當(dāng)成垃圾郵件。好煩~

          最后我們需要做的就是在定時(shí)任務(wù)中添加一個(gè)任務(wù)
          1
          2
          3
          root@ubuntu:/opt/mysh# crontab -e
          # 監(jiān)控nginx錯(cuò)誤日志,每3分鐘執(zhí)行一次
          */3 * * * * /opt/mysh/monitor_nginx_log.sh

          ps:查看定時(shí)任務(wù)使用crontab -l

          至此,我們的監(jiān)控就已經(jīng)完成了。

          參考文章:Nginx日志實(shí)現(xiàn)訪問異常報(bào)警詳解


          上面的shell腳本里面有幾個(gè)命令,這里簡單的解釋一下。
          • date

          date命令用來獲取機(jī)器當(dāng)前時(shí)間,如果需要格式化時(shí)間,可以加號(hào)(+)傳參,如下:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          date +'%Y-%m-%d %H:%M:%S'
          // 輸出格式為:2018-09-05 08:15:02

          %Y表示年
          %m表示月
          %d表示天
          %H表示小時(shí)(表示的時(shí)間是00-23)
          %M表示分鐘
          %S表示秒
          %s(表示unix時(shí)間戳的秒數(shù))

          -d<字符串>:顯示字符串所指的日期與時(shí)間。字符串前后必須加上雙引號(hào);
          -s<字符串>:根據(jù)字符串來設(shè)置日期與時(shí)間。字符串前后必須加上雙引號(hào);
          -u:顯示GMT;
          --help:在線幫助;
          --version:顯示版本信息。
          • tac

          tac命令其實(shí)就是cat的反轉(zhuǎn)的形式,tac是從最后一行往前讀取內(nèi)容,因?yàn)槲覀兪桥袛嗍欠裼行略鲥e(cuò)誤日志,所以需要從后往前遍歷,故使用tac。

          • awk

          awk是行處理器,可以依次對(duì)每一行進(jìn)行處理,-v是定義變量var=value, ‘’里面內(nèi)容是引用代碼塊, $1是指第一部分內(nèi)容(空格分隔)

          我們使用例子說明一下:

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          // 假定日志文件格式是這樣的:
          2018/09/05 06:32:50 [error] 26217#26217: *597 access forbidden by rule, client: 123.123.456.456, server: localhost, request: "GET / HTTP/1.1"
          2018/09/05 06:32:52 [error] 26217#26217: *597 access forbidden by rule, client: 123.123.456.456, server: localhost, request: "GET / HTTP/1.1"
          2018/09/05 06:32:52 [error] 26217#26217: *597 access forbidden by rule, client: 123.123.456.456, server: localhost, request: "GET /favicon.ico HTTP/1.1"

          // 命令如下:
          awk -v st="$start_time" -v et="$stop_time" -v dt="$cur_date" '{t=$2;t1=$1; if(dt==t1 && t>=st && t<=et) {print $0}}'

          // 其中 -v st="$start_time" 是賦值命令,因?yàn)楹罄m(xù)有用到比較:t>=st
          // '{t=$2;t1=$1; if(dt==t1 && t>=st && t<=et) {print $0}}' 是引用代碼塊,此處表示匹配當(dāng)前時(shí)間段內(nèi)的內(nèi)容
          // t=$2;t1=$1; 里面的 $2 是 06:32:50 這部分內(nèi)容,$1 是 2018/09/05 這部分內(nèi)容.
          // 因?yàn)?$ 是從1開始的,所以 $0 指的是整行的內(nèi)容。
          • >>

          文件內(nèi)容追加使用該命令

          1
          2
          3
          4
          5
          // 如:把123456追加到test.log的文件末尾,因?yàn)槭亲芳?,所以原有?nèi)容還在
          echo "123456" | cat >> test.log

          // 注意:單個(gè)>是會(huì)覆蓋文件的,如果執(zhí)行下面命令則會(huì)覆蓋test.log原有內(nèi)容
          echo "123456" | cat > test.log
          • tee

          讀取標(biāo)準(zhǔn)輸入的數(shù)據(jù),并將其內(nèi)容輸出成文件

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          // 輸出到標(biāo)準(zhǔn)輸出的同時(shí),保存到文件file中。如果文件不存在,則創(chuàng)建;如果已經(jīng)存在,則覆蓋
          tee file

          // 輸出到標(biāo)準(zhǔn)輸出的同時(shí),追加到文件file中
          tee -a file

          // 輸出到標(biāo)準(zhǔn)輸出兩次
          tee -

          // 上面tee進(jìn)去的monitor.log是這樣的:
          2018/09/07 03:27:01 there are new errors in nginx error.log
          2018/09/07 03:26:57 [error] 1254#1254: *109 access forbidden by rule, client: 220.181.132.194, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "123.123.123.123"
          2018/09/07 03:26:56 [error] 1254#1254: *109 access forbidden by rule, client: 220.181.132.194, server: localhost, request: "GET / HTTP/1.1", host: "123.123.123.123"
          開始發(fā)送郵件>>>
          結(jié)束郵件發(fā)送<<<
          • 再補(bǔ)充2個(gè)命令:sort | uniq
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          // 命令如下:
          cat /var/log/nginx/error.log | awk '{print $11}' | uniq -cd | sort -nr

          // 執(zhí)行結(jié)果如下:
          179 103.25.110.106,
          178 50.63.160.242,
          58 47.96.12.198,
          2 194.126.182.88,
          2 14.154.29.140,

          // 命令解釋(統(tǒng)計(jì)error.log中被禁止訪問的ip出現(xiàn)次數(shù)):
          uniq 用于去重,-c 統(tǒng)計(jì)重復(fù)次數(shù), -d 只顯示重復(fù)的數(shù)據(jù)
          sort 用于排序,-n 排序后輸出, -r 逆序排列
          本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
          打開APP,閱讀全文并永久保存 查看更多類似文章
          猜你喜歡
          類似文章
          通過nginx日志利用shell統(tǒng)計(jì)日pv和uv
          Nginx日志分析和參數(shù)詳解
          Nginx日志分割Shell腳本,按天分類存儲(chǔ)并刪除超過7天的日志
          shell腳本實(shí)例,通向shell腳本大師的必經(jīng)之路
          【轉(zhuǎn)】干貨分享
          nginx日志在windows上的切割
          更多類似文章 >>
          生活服務(wù)
          分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
          綁定賬號(hào)成功
          后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
          如果VIP功能使用有故障,
          可點(diǎn)擊這里聯(lián)系客服!

          聯(lián)系客服