基于Python的关键字监控及告警


Posted in Python onJuly 06, 2017

为了解决日志文件监控的问题, 使用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")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现模拟时钟代码推荐
Nov 08 Python
实例解析Python中的__new__特殊方法
Jun 02 Python
Python中的Descriptor描述符学习教程
Jun 02 Python
详解python里使用正则表达式的分组命名方式
Oct 24 Python
Python中的上下文管理器和with语句的使用
Apr 17 Python
Python深拷贝与浅拷贝用法实例分析
May 05 Python
对Python中画图时候的线类型详解
Jul 07 Python
用sqlalchemy构建Django连接池的实例
Aug 29 Python
调用其他python脚本文件里面的类和方法过程解析
Nov 15 Python
Pandas实现一列数据分隔为两列
May 18 Python
python map比for循环快在哪
Sep 21 Python
Jupyter Notebook内使用argparse报错的解决方案
Jun 03 Python
Python中装饰器兼容加括号和不加括号的写法详解
Jul 05 #Python
利用python模拟sql语句对员工表格进行增删改查
Jul 05 #Python
利用python实现简单的循环购物车功能示例代码
Jul 05 #Python
用python做一个搜索引擎(Pylucene)的实例代码
Jul 05 #Python
Python对象类型及其运算方法(详解)
Jul 05 #Python
python数据预处理之将类别数据转换为数值的方法
Jul 05 #Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
Jul 04 #Python
You might like
古巴咖啡 Cubita琥爵咖啡 独特的加勒比海风味咖啡
2021/03/06 新手入门
PHP4实际应用经验篇(1)
2006/10/09 PHP
PHP注释实例技巧
2008/10/03 PHP
一个PHP数组应该有多大的分析
2009/07/30 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十一)
2014/06/25 PHP
Swoole-1.7.22 版本已发布,修复PHP7相关问题
2015/12/31 PHP
tp5实现微信小程序多图片上传到服务器功能
2018/07/16 PHP
PHP PDOStatement::getAttribute讲解
2019/02/01 PHP
Javascript与vbscript数据共享
2007/01/09 Javascript
一些mootools的学习资源
2010/02/07 Javascript
JQuery 动画卷页 返回顶部 动画特效(兼容Chrome)
2010/02/15 Javascript
firefox火狐浏览器与与ie兼容的2个问题总结
2010/07/20 Javascript
基于jquery实现点击左右按钮图片横向滚动
2013/04/11 Javascript
jQuery实现的选择商品飞入文本框动画效果完整实例
2016/08/10 Javascript
微信小程序 在线支付功能的实现
2017/03/14 Javascript
BACKBONE.JS 简单入门范例
2017/10/17 Javascript
vue 组件中slot插口的具体用法
2018/04/03 Javascript
对vue2.0中.vue文件页面跳转之.$router.push的用法详解
2018/08/24 Javascript
vue swipe自定义组件实现轮播效果
2019/07/03 Javascript
[01:25:09]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第二场
2014/05/24 DOTA
python安装cx_Oracle模块常见问题与解决方法
2017/02/21 Python
Django内容增加富文本功能的实例
2017/10/17 Python
python使用jieba实现中文分词去停用词方法示例
2018/03/11 Python
python requests 测试代理ip是否生效
2018/07/25 Python
Linux下多个Python版本安装教程
2018/08/15 Python
python opencv将图片转为灰度图的方法示例
2019/07/31 Python
Python常用编译器原理及特点解析
2020/03/23 Python
利用pyecharts读取csv并进行数据统计可视化的实现
2020/04/17 Python
Python基于pillow库实现生成图片水印
2020/09/14 Python
FitFlop澳大利亚官网:英国符合人体工学的鞋类品牌
2017/06/05 全球购物
婴儿地球:Baby Earth
2018/12/25 全球购物
北京奥运会口号
2014/06/21 职场文书
社区扶贫帮困工作总结
2015/05/20 职场文书
2016年质量月活动总结报告
2016/04/05 职场文书
Go语言设计模式之结构型模式
2021/06/22 Golang
SpringBoot全局异常处理方案分享
2022/05/25 Java/Android