前言
由于单位尚没有完善的监控制度,且项目也较少,使用开源的监控组件有点小题大做,因此研究了基于python的错误日志监控,功能如下:
- 监听error日志文件增量数据(每分钟的增量数据)
- 提供白名单功能,白名单内的异常不发送通知
- 有异常通过邮件发送通知
具体实现
前置条件
- 日志需要进行级别划分,错误日志需要与info日志分开,防止日志过大导致宿主机爆栈
- 邮箱开通对应服务,用于告警邮件发送
- python3环境
画一下流程图
废话不多说直接上代码代码风格是按照java来的 -_-
#!/usr/bin/env python3
#!coding:utf-8
import subprocess
import datetime
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
import os
import string
#告警接收人
toUser = ['zhiaiyahong@yhwch.com']
#异常白名单,白名单内的异常不通知,基于字符串包含进行过滤
excludeClassErrorList = ['TripleDesCryptoHandler']
mySender='xxx@qq.com' # 发件人邮箱账号 改为本人账号
myPass = 'xxxx' # 发件人邮箱密码(当时申请smtp给的口令)
def grep(filename, arg):
process = subprocess.Popen(['grep', '-n', arg, filename], stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
return stdout
def sendMail(toUser,content,titles):
msg=MIMEText(content,'html','utf-8')
msg['From']=formataddr(["异常日志监控告警",mySender])
msg['To']=",".join(toUser)
msg['Subject']=titles
server=smtplib.SMTP_SSL("smtp.qq.com", 465)
server.login(mySender, myPass)
server.sendmail(mySender,toUser,msg.as_string())
server.quit()# 关闭连接
print("邮件发送完毕")
def excludeClassError(errorItem):
for x in excludeClassErrorList:
if x in errorItem:
return True
return False
nowDate = datetime.datetime.now()
nowSecond = (nowDate+datetime.timedelta(minutes=-1)).strftime("%Y-%m-%d %H:%M")
errorFileName = nowDate.strftime("%Y-%m-%d")
errorFileName = "/opt/logs/error-"+errorFileName+".log"
if not os.path.isfile(errorFileName):
print(errorFileName,"文件不存在,无错误日志,万事大吉")
else:
printout = grep(errorFileName,nowSecond)
printout = printout.decode()
errorList = printout.split('\n')
errorInfo = ""
for x in errorList:
if(excludeClassError(x)):
print("忽略异常",x)
else:
errorInfo = errorInfo + x
if(errorInfo == ''):
print(nowSecond,"无错误日志万事大吉")
else:
print(errorInfo)
content = "时间:"+nowSecond+"<br>异常简略:"+errorInfo+"<br>详细请登录服务器查看日志,目录:"+errorFileName
titles = "【大事】大批空指针来袭,祝发际线高升"
sendMail(toUser,content,titles)