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'
console_hander = logging.StreamHandler()
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')
logger.addHandler(console_hander)
logger.addHandler(th)
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()
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():
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 = ""
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_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:
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)
def check_cpu_alarm(cpu):
logger.info('check_cpu_alarm start')
while True:
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()
四、未解决问题
- 发送邮件后,没有处理报警的能力,后续的话尝试加入自动处理报警的能力
|