5. 監控磁碟使用率

最愛喝酸奶發表於2019-01-15

雖然對於磁碟的監控屬於最基礎的監控,但是很多時候往往因為疏忽而忽略監控磁碟,最終導致事故發生,磁碟監控還是需要重視起來。本案例就是要監控磁碟使用率。

具體要求如下:

1)每分鐘檢測一次磁碟狀況;

2)當磁碟空間使用率或inode使用率高於90%,需要發郵件告警,假設收件郵箱為admin@admin.com ;

3)統計使用率超過90%的分割槽所有子目錄的大小,並把排名前3的子目錄寫到郵件內容中發給上面的郵箱;

4)第一次告警後,如果沒有及時處理,則需要每隔30分鐘告警一次;

5)每分鐘指令碼執行時,需要檢查指令碼是否執行完,如果沒有執行完則本次不執行。

郵件指令碼如下:

#!/usr/bin/python
#coding:utf-8
import smtplib
from email.mine.text import MIMEText
import sys
mail_host = 'stmp.163.com'
mail_user = 'test@163.com'
mail_pass = 'your_mail_password'
mail_postfix = '163.com'
def send_mail(to_list,subject,content):
    me = "zabbix 監控告警平臺"+"<"+mail_user+"@"+mail_postfix+">"
    msg = MIMEText(content,'plain','utf-8')
    msg['Subject'] = subject
    msg['From'] = me
    msg['to'] = to_list
    try:
        s = smtplib:SMTP()
        s.connect(mail_host)
        s.login(mail_user,mail_pass)
        s.sendmail(me,to_list,msg.as_string())
        s.close()
        return True
    except Exception,e:
        print str(e)
        return False
if __name__ == "__main__"
    send_mail(sys.argv[1], sys.argv[2], sys.argv[3])

參考指令碼如下:

# vim /usr/local/sbin/disk_check.sh
#!/bin/bash
#監控磁碟使用情況,做郵件告警及告警收斂

#把指令碼名字存入變數s_name
s_name=`echo $0|awk -F '/' '{print $NF}'`

#定義收件人郵箱
mail="/usr/local/sbin/mail.py"
mail_user=admin@admin.com


#定義檢查磁碟空間使用率函式
chk_sp()
{
    df -m |sed '1d' |awk -F '%| +' '$5>90 {print $7,$5}' > /tmp/chk_sp.log
    n=`wc -l /tmp/chk_sp.log |awk '{print $1}'`
    if [ $n -gt 0 ]
    then
        tag=1
        for d in `awk '{print $1}' /tmp/chk_sp.log`
        do
            find $d -type d |sed '1d' |xargs du -sm |sort -nr |head -3           #找到使用率超過90%的分割槽下面大小排名前3的子目錄
        done > /tmp/most_sp.txt
    fi
}

#定義檢查inode使用率函式
chk_in()
{
    df -i |sed '1d' |awk -F '%| +' '$5>90 {print $7,$5}' > /tmp/chk_in.log
    n=`wc -l /tmp/chk_in.log |awk '{print $1}'`
    if [ $n -gt 0 ]
    then
        tag=2
    fi
}

#定義告警函式
m_mail()
{
    log=$1
    t_s=`date +%s`
    t_s2=`date -d "1 hour ago" +%s`
    if [ ! -f /tmp/$log ]
    then
        touch /tmp/$log         #建立$log檔案
        chattr +a /tmp/$log         #增加a許可權,僅允許追加內容
        echo $t_s2 >> /tmp/$log         #第一次告警,可直接寫入1小時前的時間戳
    fi
    
    t_s2=`tail -1 /tmp/$log |awk '{print $1}'`          #檢視$log檔案最後一行的時間戳
    echo $t_s >> /tmp/$log          #取出最後一行即上次告警的時間戳後,立即寫入當前的時間戳
    v=$[$t_s-$t_s2]         #取兩次時間戳差值
    if [ $v -gt 1800 ]          #差值如果超過1800s,立即發郵件
    then
        python $mail $mail_user "磁碟使用率超過90%" "`cat $2`" 2>/dev/null         #發郵件,$2為mail函式第二個引數,這裡是一個檔案
        echo "0" > /tmp/$log.count          #定義計時器臨時檔案,並寫入0
    else
        if [ ! -f /tmp/$log.count ]
        then
            echo "0" > /tmp/$log.count          #如果計時器臨時檔案不存在,需要建立並寫入0
        fi
        
        nu=`cat /tmp/$log.count`
        nu2=$[$nu+1]        #30分鐘內每發生一次告警,計數器加1
        echo $nu2 > /tmp/$log.count
        
        if [ $nu2 -gt 30 ]
        then
            python $mail $mail_user "磁碟使用率超過90%已經持續30分鐘了" "`cat $2`" 2>/dev/null
            echo "0" > /tmp/$log.count          #第二次告警後,計數器歸0
        fi
    fi
}

#把程式情況存入臨時檔案
ps aux |grep "$s_name" |grep -vE "$$|grep" > /tmp/ps.tmp
p_n=`wc -l /tmp/ps.tmp |awk '{print $1}'`

#當程式數大於0,則說明上次的指令碼還未執行完
if [ $p_n -gt 0 ]
then
    exit
fi

chk_sp
chk_in

if [ $tag == 1 ]          
then
    m_mail chk_sp /tmp/most_sp.txt          #執行m_mail函式傳送郵件,$1是chk_sp,$2是/tmp/most_sp.txt
elif [ $tag == 2 ]
then
    m_mail chk_in /tmp/chk_in.log           #執行m_mail函式傳送郵件,$1是chk_in,$2是/tmp/chk_in.log
fi

增加計劃任務:

* * * * * /bin/bash /usr/local/sbin/disk_check.sh

指令碼中,

1)$0表示指令碼本身,awk中$NF表示最後一段的值,去掉絕對路徑,剩下指令碼名字寫入變數$s_name

2)$$為本程式PID,grep -vE "$$|grep" 排除本程式和grep程式


相關文章