python中使用gevent协程实现系统监控报警
文章目录
- python中使用gevent协程实现系统监控报警
- 一、版本说明
- 二、主要逻辑与功能
- 三、整体代码
- 四、未解决问题
一、版本说明
版本 | 更新日期 |
1.0.Alpha | 2022-02-26 |
二、主要逻辑与功能
主要功能还是监控系统信息并报警
- 内存利用率大于80%。发送告警邮件
- CPU利用率大于80%。发送告警邮件
- 每晚12点定时发送系统信息,包括但不限于网卡信息、主机名与IP地址
三、整体代码
代码逻辑比较简单,很容易就能看懂
注意:请修改代码中的邮件发送参数,具体百度网易邮箱开启SMTP
代码如下:
import psutil, time, logging, gevent, smtplib, datetime, schedule, socket
from gevent import monkey
from email.mime.text import MIMEText
from logging import handlers
fomatter = logging.Formatter(' %(levelname)s %(asctime)s - %(funcName)s - %(thread)s [%(message)s]')
# 创建日志器对象
logger = logging.getLogger()
# 日志级别总开关
logger.setLevel("INFO")
# 设置日志文件
logFile = './default_monitor.log'
# 创建日志文件hander
# fileHandler = logging.FileHandler(logFile, mode='a')
# fileHandler.setLevel(logging.INFO)
# 创建控制台hander
console_hander = logging.StreamHandler()
# 创建控制台hander日志等级
console_hander.setLevel(level='INFO')
# 设置日志格式
console_hander.setFormatter(fomatter)
th = handlers.TimedRotatingFileHandler(filename=logFile, when='D', backupCount=3, encoding='utf-8')
th.setFormatter(fomatter)
th.setLevel(level='INFO')
# 添加日志hander
logger.addHandler(console_hander)
logger.addHandler(th)
# logger.addHandler(fileHandler)
# 设置邮件发送参数,需要自己修改成自己的参数
mail_host = 'smtp.163.com'
mail_user = 'cc17854388872@163.com'
mail_pass = 'VBYZZtttttRDQJAXN'
sender = 'cc17854388872@163.com'
# 接收方邮箱地址
receivers = ['1849999179@qq.com']
# 获取当前时间
current_time = datetime.datetime.now()
# 使用gevent中的monky不修改原来使用的python标准库函数的程序的情况下,将程序转换成可以使用gevent框架的异步程序。
monkey.patch_all()
def print_system_info(mem, cpu):
while True:
# 闲的没事干加点日志输出吧
logger.info(f'Current Memory utilization is {mem.percent}%')
logger.info(f'Current CPU utilization is {cpu}%')
time.sleep(10)
# 系统信息定时发送函数
def system_sender():
# 创建任务调用mail_sender并传递两个参数,每天晚上12点定时发送系统信息邮件
schedule.every().day.at("20:37").do(mail_sender, title='system info', content=get_system())
logger.info('scheduler starting ')
while True:
schedule.run_pending()
time.sleep(1)
# 获取系统信息函数
def get_system():
date = ""
# 服务器基本信息,主机名与IP地址
myname = socket.getfqdn(socket.gethostname())
myaddr = socket.gethostbyname(myname)
# 用户信息
now_time = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
start_time = datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H: %M: %S")
# CPU信息
cpu_num = psutil.cpu_count(logical=False)
cpu = (str(psutil.cpu_percent(1))) + '%'
# 内存信息
total = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0 * 1024.0), 2)) + 'G'
total_used = str(round(psutil.virtual_memory().used / (1024.0 * 1024.0 * 1024.0), 2)) + 'G'
total_free = str(round(psutil.virtual_memory().free / (1024.0 * 1024.0 * 1024.0), 2)) + 'G'
memory = str(psutil.virtual_memory().percent) + '%'
# 网卡信息
net = psutil.net_io_counters()
bytes_sent = '{0:.2f} Mb'.format(net.bytes_recv / 1024 / 1024)
bytes_rcvd = '{0:.2f} Mb'.format(net.bytes_sent / 1024 / 1024)
date += "<br/>当前用户: " + str(psutil.users()[0][0]) + '<br/>'
date += "<br/>当前主机:" + str(myname) + '<br/>'
date += "<br/>IP 地址: " + myaddr + '<br/>'
date += "<br/>系统当前时间: " + now_time + '<br/>'
date += "<br/>系统开机时间: " + start_time + '<br/>'
date += "<br/>CPU个数: " + str(cpu_num) + '<br/>'
date += "<br/>CPU使用率: " + cpu + '<br/>'
date += "<br/>内存: " + total + '<br/>'
date += "<br/>内存已使用: " + total_used + '<br/>'
date += "<br/>剩余内存: " + total_free + '<br/>'
date += "<br/>内存使用率: " + memory + '<br/>'
date += "<br/>网卡发送流量: " + bytes_sent + '<br/>'
date += "<br/>网卡接收流量: " + bytes_rcvd + '<br/>'
return date
def mail_sender(title, content):
message = MIMEText(content, 'plain', 'utf-8')
message['Subject'] = title
message['From'] = sender
message['To'] = receivers[0]
try:
smtpObj = smtplib.SMTP()
# 连接到服务器
smtpObj.connect(mail_host, 25)
# 登录到服务器
smtpObj.login(mail_user, mail_pass)
# 发送
smtpObj.sendmail(
sender, receivers, message.as_string())
# 退出
smtpObj.quit()
logger.info(f'Mail sent {title} successfully')
except smtplib.SMTPException as e:
logger.error('error', e) # 打印错误
def check_memory_alarm(mem):
logger.info('check_memory_alarm start')
while True:
# 内存利用率大于80%发送告警邮件
if int(mem.percent) > 80:
content = f'<br/>Current time:{current_time} </br> <br/>Memory utilization exceeds 80%</br>'
mail_sender('memory warning', content)
break
time.sleep(5)
# cpu告警模块
def check_cpu_alarm(cpu):
logger.info('check_cpu_alarm start')
while True:
# cpu利用率大于80%发送告警邮件
if int(cpu) > 80:
content = f'<br/>Current time:{current_time} </br> <br/>CPU utilization exceeds 80%</br>'
mail_sender('cpu warning', content)
break
time.sleep(5)
def main():
mem = psutil.virtual_memory()
cpu = psutil.cpu_percent(interval=1)
gevent.joinall(
[
gevent.spawn(print_system_info, mem, cpu),
gevent.spawn(check_memory_alarm, mem),
gevent.spawn(check_cpu_alarm, cpu),
gevent.spawn(system_sender)
]
)
if __name__ == '__main__':
main()
四、未解决问题
- 发送邮件后,没有处理报警的能力,后续的话尝试加入自动处理报警的能力