20.20 告警系統主腳本(main.sh)php
20.21 告警系統配置文件mysql
20.22 告警系統監控項目linux
20.20 告警系統主腳本(main.sh):nginx
~1.約定:把之後全部的shell腳本放在/usr/local/sbin下,也方便咱們查找sql
~2.咱們先去定義監控系統的各個目錄,而後再定義主腳本。由於是分佈式的,因此每一臺機器都要這麼去作。固然你事先建立好各個目錄,以及各個腳本,而後再把這臺機器上的全部的腳本直接拷貝各個機器上去,而後再去作一些更改。就能夠了shell
~3.main.sh內容:(如下內容的表達式,對於各個版本可能有差別,要測試一下修改適用)實例中有詳細的解釋數據庫
#!/bin/bashvim
#Written by aming.bash
# 是否發送郵件的開關服務器
export send=1
# 過濾ip地址
export addr=`/sbin/ifconfig |grep -A1 "ens33: "|awk '/inet/ {print $2}'`
dir=`pwd`
# 只須要最後一級目錄名
last_dir=`echo $dir|awk -F'/' '{print $NF}'`
# 下面的判斷目的是,保證執行腳本的時候,咱們在bin目錄裏,否則監控腳本、郵件和日誌頗有可能找不到
if [ $last_dir == "bin" ] || [ $last_dir == "bin/" ]; then
conf_file="../conf/mon.conf"
else
echo "you shoud cd bin dir"
exit
fi
exec 1>>../log/mon.log 2>>../log/err.log
echo "`date +"%F %T"` load average"
/bin/bash ../shares/load.sh
#先檢查配置文件中是否須要監控502
if grep -q 'to_mon_502=1' $conf_file; then
export log=`grep 'logfile=' $conf_file |awk -F '=' '{print $2}' |sed 's/ //g'`
/bin/bash ../shares/502.sh
fi
實例:
[root@axinlinux-01 ~]# cd /usr/local/sbin #之後把全部的腳本都放在這個目錄下
[root@axinlinux-01 sbin]# mkdir mon #先建立主目錄
[root@axinlinux-01 sbin]# cd mon #進入到這個主目錄,而後咱們再來建立各個子目錄
[root@axinlinux-01 mon]# ls
[root@axinlinux-01 mon]# mkdir bin conf shares log mail #建立子目錄。
以上,根據下圖建立主目錄,以及各個子目錄:
(主目錄 mon) ____________________|_______________________________
| | | | |
bin conf shares mail log
| | | | |
[main.sh] [ mon.conf] [load.sh 502.sh] [mail.py mail.sh] [ mon.log err.log ]
[root@axinlinux-01 mon]# cd bin #進入到bin下。就是咱們這一節要建立的主腳本main.sh
這個main.sh主腳本,做爲咱們的一個入口。你應該去判斷配置文件,看看某某某監控項目是否須要監控。還須要去調用須要監控的子腳本
#!/bin/bash
#Written by aming.
# 是否發送郵件的開關
export send=1 #意思就是隻要把send改成1,那麼他下面全部監控的項目都會發送郵件。好比咱們系統處於維護狀態,可能須要關閉全部的服務,那這時候就須要把告警關閉,避免誤報(形成領導追究責任)。因此應該設置一個總開關。那維護狀態下咱們就把這個告警關閉
以上,只是把告警關閉,監控仍是繼續監控
!export的意思是他的變量會應用到全部的子腳本里面。也就是後續調用的全部的監控項目的子腳本,都會使用到send的變量!
# 過濾ip地址
export addr=`/sbin/ifconfig |grep -A1 "ens33: "|awk '/inet/ {print $2}'` #這個就是每一臺機器使用的IP地址,固然也能夠定義這臺機器的hostname。會使咱們知道告警的時候,是哪一臺機器的告警。目的就是告訴咱們發郵件的是哪一臺機器。由於是分佈式的,每一臺機器獨立運行
!這條表達式要在該機器上測試,是否出現該機器的IP!測試的時候要注意網卡的名字,以及須要上報的IP地址是哪個就寫哪個,好比這裏須要上報的是ens33網卡
dir=`pwd` #定義一下當前腳本所在的目錄。由於不能保證全部的監控mon這個目錄,都放在了/use/local/sbin/下。避免別人找不到,這個目錄不是固定死的,因此要用pwd這個命令來找到所在的路徑在哪裏,由於咱們已經cd進/usr/local/sbin/mon/bin下了,因此能pwd到
# 只須要最後一級目錄名
last_dir=`echo $dir|awk -F'/' '{print $NF}'` #以上dir=`pwd`,咱們只須要最後一級目錄名(last_dir)便可。等下回解釋爲何會這樣用
因此,以上,last_dir=`echo $dir|awk -F'/' '{print $NF}'`後面的表達式,出來的路徑末尾是否是bin就能夠了,由於(接上面的dir=`pwd`,咱們已經cd進/usr/local/sbin/mon/bin下了)。一樣須要測試,能夠這樣測試:[root@axinlinux-01 bin]# pwd
/usr/local/sbin/mon/bin
[root@axinlinux-01 bin]# echo "/usr/local/sbin/mon/bin" |awk -F'/' '{print $NF}'
bin #輸出結果爲bin目錄,爲表達式正確。這就是我麼想要的,也就是last_dir=bin目錄
# 下面的判斷目的是,保證執行腳本的時候,咱們在bin目錄裏,否則監控腳本、郵件和日誌頗有可能找不到
做用就告訴用戶你沒有在這個目錄下,咱們後面的各個執行操做無法往下進行了。由於咱們腳本里用的好多都是相對路徑,因此必須在bin目錄下
if [ $last_dir == "bin" ] || [ $last_dir == "bin/" ]; then #若是last_dir不是bin,或者是bin/,就會echo你必需要到bin下去
conf_file="../conf/mon.conf" #定義配置文件所在的路徑,這個就是相對路徑
else
echo "you shoud cd bin dir"
exit
fi
exec 1>>../log/mon.log 2>>../log/err.log #定義輸出正確的日誌和錯誤的日誌
echo "`date +"%F %T"` load average" #打標記,定義日期年月日分秒,是爲了求出系統負載。系統負載是每臺機器必需要監控的項目
/bin/bash ../shares/load.sh #直接調用了子腳本,監控系統負載,不須要判斷,也不須要開關。找到這個子腳本直接執行他就能夠了
#先檢查配置文件中是否須要監控502狀態碼(nginx)
if grep -q 'to_mon_502=1' $conf_file; then #先到配置文件看一下,他有沒有讓咱們監控502
export log=`grep 'logfile=' $conf_file |awk -F '=' '{print $2}' |sed 's/ //g'` #怎麼看呢,就是用表達式把是否開關的相關的關鍵詞過濾出來。若是是就執行,若是不是就不執行
/bin/bash ../shares/502.sh
fi
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20.21 告警系統配置文件(mon.conf):
mon.conf內容:
(其實就是定義一些開關、日誌的路徑,好比監控MySQL的時候,定義用戶名、密碼、IP、port等等)
## to config the options if to monitor
## 定義mysql的服務器地址、端口以及user、password
to_mon_cdb=0 ##0 or 1, default 0,0 not monitor, 1 monitor
db_ip=10.20.3.13
db_port=3315
db_user=username
db_pass=passwd
## httpd 若是是1則監控,爲0不監控
to_mon_httpd=0
## php 若是是1則監控,爲0不監控
to_mon_php_socket=0
## http_code_502 須要定義訪問日誌的路徑
to_mon_502=1
logfile=/data/log/xxx.xxx.com/access.log
## request_count 定義日誌路徑以及域名
to_mon_request_count=0
req_log=/data/log/www.discuz.net/access.log
domainname=www.discuz.net
實例:
[root@axinlinux-01 bin]# cd ..
[root@axinlinux-01 mon]# ls
bin conf log mail shares
[root@axinlinux-01 mon]# vim conf/mon.conf #配置文件必需要在conf目錄下,而且名字不能隨便改,由於咱們已經在主腳本里定義爲mon.conf了
## to config the options if to monitor
## 定義mysql的服務器地址、端口以及user、password
to_mon_cdb=0 ##0 or 1, default 0,0 not monitor, 1 monitor #意思是說你是否要監控cbd數據庫,若是監控就=1,若是不監控就=0。
在主腳本里會去過濾這些數字,若是是1就自行子腳本,不是1就不執行子腳本
db_ip=10.20.3.13
db_port=3315
db_user=username
db_pass=passwd
## httpd 若是是1則監控,爲0不監控 #這個是監控的httpd
to_mon_httpd=0
## php 若是是1則監控,爲0不監控 #這個是監控的php socket
to_mon_php_socket=0
## http_code_502 須要定義訪問日誌的路徑 #這個是監控的502
to_mon_502=1
logfile=/data/log/xxx.xxx.com/access.log #由於監控502的話要去到日誌文件裏,到你的訪問日誌裏去查看狀態碼。因此必需要有一個日誌做爲過濾的對象,針對哪一個日誌去操做
## request_count 定義日誌路徑以及域名 #這個是監控請求數
to_mon_request_count=0
req_log=/data/log/www.discuz.net/access.log #監控請求數,也是經過這個日誌來的。因此要定義req_log
domainname=www.discuz.net #還要定義上面req_log所涉及到的域名
以上的配置文件怎麼去定義取決於你的子腳本,子腳本里面須要用到什麼樣的資源。
也就是咱們能夠把這些寫入到子腳本里面去,可是前提是機器很少的狀況下。可是咱們爲何要把這些單獨拿出來。目的是兼容性等,單獨寫到配置文件裏,改起來很方便,省的在主腳本里修改子腳本。就像咱們在主腳本里就直接寫了系統負載,也沒有定義開關,由於他是必需要監控的
說白了就是主腳本里找出要監控的項目,在這裏定義是否要監控,它的開關是1仍是0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20.22 告警系統監控項目(子腳本):
下面咱們再來定義幾個子腳本,也就是監控項目
~1.告警系統load.sh:
這個是必需要有的,由於咱們在主腳本里已經定義了,任何一臺機器都要監控系統負載。也就是這個load.sh。如下就是這個load怎麼過濾出來
~1.load.sh內容
#! /bin/bash
##Writen by aming##
load=`uptime |awk -F 'average:' '{print $2}'|cut -d',' -f1|sed 's/ //g' |cut -d. -f1`
if [ $load -gt 10 ] && [ $send -eq "1" ]
then
echo "$addr `date +%T` load is $load" >../log/load.tmp
/bin/bash ../mail/mail.sh aming_test@163.com "$addr\_load:$load" `cat ../log/load.tmp`
fi
echo "`date +%T` load is $load"
實例:
[root@axinlinux-01 shares]# vim load.sh
#! /bin/bash
##Writen by aming##
load=`uptime |awk -F 'average:' '{print $2}'|cut -d',' -f1|sed 's/ //g' |cut -d. -f1` #要測試是否出來的數字是系統負載的值
if [ $load -gt 10 ] && [ $send -eq "1" ] #當這個值大於10的時候而且send(咱們在主腳本里定義的主開關)等於1的時候(容許發郵件的時候)
then #而後怎麼樣呢
echo "$addr `date +%T` load is $load" >../log/load.tmp #先輸出這個日誌(哪一個IP、什麼時間、什麼值)。load.tmp這個文件是咱們下面要發郵件的文件
/bin/bash ../mail/mail.sh aming_test@163.com "$addr\_load:$load" `cat ../log/load.tmp`
fi #調用咱們以前寫的mail.sh發郵件
echo "`date +%T` load is $load"
~2.告警系統502.sh:
502.sh內容
#! /bin/bash
d=`date -d "-1 min" +%H:%M`
c_502=`grep :$d: $log |grep ' 502 '|wc -l`
if [ $c_502 -gt 10 ] && [ $send == 1 ]; then
echo "$addr $d 502 count is $c_502">../log/502.tmp
/bin/bash ../mail/mail.sh $addr\_502 $c_502 ../log/502.tmp
fi
echo "`date +%T` 502 $c_502"
實例:
[root@axinlinux-01 shares]# vim 502.sh
#! /bin/bash
d=`date -d "-1 min" +%H:%M` #找到一分鐘之前的日誌出來
c_502=`grep :$d: $log |grep ' 502 '|wc -l` #而後再過濾502,看看有多少行
if [ $c_502 -gt 10 ] && [ $send == 1 ]; then #大於10而且容許發郵件,而後
echo "$addr $d 502 count is $c_502">../log/502.tmp #輸出一個臨時的文件
/bin/bash ../mail/mail.sh $addr\_502 $c_502 ../log/502.tmp #調用mail.sh發郵件
fi
echo "`date +%T` 502 $c_502" #最後輸出有多少個502
~3.告警系統disk.sh(磁盤使用率):
disk.sh內容(思路是,把全部的分區挨個看一下,用到了循環)
#! /bin/bash
##Writen by aming##
rm -f ../log/disk.tmp
for r in `df -h |awk -F '[ %]+' '{print $5}'|grep -v Use` #這裏的awk使用了多個分隔符空格與百分號,都生效
do
if [ $r -gt 90 ] && [ $send -eq "1" ]
then
echo "$addr `date +%T` disk useage is $r" >>../log/disk.tmp
fi
if [ -f ../log/disk.tmp ]
then
df -h >> ../log/disk.tmp
/bin/bash ../mail/mail.sh $addr\_disk $r ../log/disk.tmp
echo "`date +%T` disk useage is nook"
else
echo "`date +%T` disk useage is ok"
fi