基於Python 的關鍵字監控及告警


為了解決日志文件監控的問題, 使用python腳本完成了基於關鍵字的告警功能 

環境 python 2.7 

依賴包 time \ traceback \ filelock \ logging 

 

代碼如下:

#!/bin/python
#coding:utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import re
import os
from urllib import urlencode
import logging
import filelock
import time
import traceback

#config.conf
#文件1:關鍵字A|關鍵字B:出現次數:告警方式:聯系方式:聯系組:某某異常
#文件2:關鍵字C|關鍵字D:出現次數:告警方式:聯系方式:聯系組:某某異常

#rc.local增加
#sudo -u monitor /bin/bash -x /home/apps/logmon-job/deploy_py.sh

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S',
                    filename='/home/logs/monitor/logmon.log',
                    #filename='/Users/mac/Desktop/logmon/logmon.log',
                    filemode='a')

basDir='/home/apps/logmon-job/'

posFiles=basDir+'/pos.log'
configFile=basDir+'config.conf'

def readOnly(filename):
    return open(filename,'r')
    # pass

def readWrite(filename):
    return open(filename,'rw')
    # pass
def writeOnly(filename):
    return open(filename,'w')
    # pass

# def closesfile():
#     pass

def getStartPosLog(posFiles):
    txt=readOnly(posFiles)
    result={}
    for i in txt :
        filename,pos=i.split(':')
        if filename != '' :
            result[filename]=pos
    return result
    txt.close()

def rematch(txt,regular):
    resultList=[]
    for t in txt.split(r'\n') :
        # print t
        # pattern = re.compile(r':')
        pattern = re.compile(regular)

        resultList=(pattern.findall(t))
    try :
        # print '匹配結果為',resultList 
        return len(resultList),regular , resultList[0]
    except Exception as e :
        print e 
        return 0 , regular , ''
    # pass

def getEndPost(f):
    filename=readOnly(f)
    try :
        nowpos=filename.tell()
        filename.seek(0,2)
        endpos=filename.tell()
        filename.seek(nowpos,0)
    except :
        endpos = 0
    filename.close()
    return endpos 
    # pass

def getDistinct(startpos,endpos):
    return endpos-startpos

def getText(f,startpos,endpos):

    filename=readOnly(f)
    filename.seek(startpos,0)
    textLength=getDistinct(startpos,endpos)
    text=filename.read(textLength)
    filename.close()
    return text

def updatePosLog(posResult,posFiles):
    f=writeOnly(posFiles)
    # print 'posResult ',posResult
    for k in posResult.keys() :
        v=posResult[k]
        f.writelines('%s:%s\n' %(k,v))
    f.close()

    pass

def getAlterConfi(filename):
    #文件:關鍵字:出現次數:告警方式:聯系方式:聯系組
    f=readOnly(filename)
    result={}
    for lines in f.readlines():
        # print lines
        try :
            filename , key , count , alterType , alterAddress , alterGroup ,alterMessage= lines.strip('\n').split(":")
            result[filename]={}
            result[filename]["key"]         =key
            result[filename]["count"]       =count
            result[filename]["alterType"]   =alterType
            result[filename]["alterAddress"]=alterAddress
            result[filename]["alterGroup"]  =alterGroup
            result[filename]["alterMessage"]=alterMessage
        except Exception as e:
            print e
            print '錯誤的配置 %s' % (lines.strip('\n'))
            pass
    return result

def sendSms(account,message):

    data={
        'accounts':account  ,
        'templateName':'opalert' ,
        'alertcontent':message ,
    }
    encodeMessage=urlencode(data)

    #正式時需要開啟
    os.system('curl -I "http://10.1.1.146:8080/sms/send?%s" ' % ( encodeMessage ) )

def main():
    global posFiles
    global configFile

    AlterConfi=getAlterConfi(configFile)
    print AlterConfi
    posResult=getStartPosLog(posFiles)
    posResult_bak=getStartPosLog(posFiles)
    # print posResult
    for filename in AlterConfi.keys() :
        keyDict=AlterConfi[filename]
        print '開始檢查文件 ',filename
        #print  rematch(filename,r'#')[0] 
        if not os.path.exists(filename):
            print 'file "%s" not exist ,pass' % (filename)
            # continue
        if os.path.exists(filename):

            
            endpos  = getEndPost(filename)

            if endpos == 0 :
                print 'file "%s" is empty ,pass' % (filename)
            else :
                try :
                    startpos=  int(posResult[filename])
                except :
                    startpos = 0
                print 'startpos is %.f , endpos is %.f' %(startpos ,endpos)

                #處理切割后,偏移量歸位
                if startpos > endpos :
                    startpos = 0

                text = getText(filename,startpos,endpos)
                # print '%s text is  : '%(filename) , text

                #分析關鍵字
                #print AposlterConfi[filename]
                matchCount , regular , resultList = rematch(text,keyDict['key'])
                print '匹配關鍵字',regular , '匹配長度為', matchCount , '關鍵字告警閾值' ,keyDict['count'] , '關鍵字' , resultList

                if int(matchCount) >= int(keyDict['count']) :
                    print 'alterGroup len is ',len(keyDict['alterGroup'])
                    print 'alterType len is ' ,len(keyDict['alterType'])
                    if len(keyDict['alterGroup']) > 0:
                        pass
                    if len(keyDict['alterType']) >0:
                        if keyDict['alterType'].upper() == 'SMS' :
                            for account in keyDict['alterAddress'].split(',') :
                                if len(account) >0 :
                                    sendSms(account,'發現%s 告警,關鍵字:%s  ,出現次數:%s ' %(keyDict['alterMessage'] , resultList , matchCount ))
                        pass
                #記錄末尾偏移量
                posResult_bak[filename]=endpos


        
    print '打印文件偏移量信息',posResult_bak
        
    #正式時需要開啟
    updatePosLog(posResult_bak,posFiles)


if __name__ == '__main__':
    lock = filelock.FileLock("/home/apps/logmon-job/logmon.py.lock")
    if lock:
        logging.info("CaiWeiCheng Get Lock.start!!!")
    try:
        with lock.acquire(timeout=5):
            while 1 :
                main()
                time.sleep(60)
            # pass
    #except filelock.timeout :
    except Exception as e :
        print traceback.format_exc()
        print "timeout"         
        logging.warning("get file lock timeout")

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM