python实时监控电脑运行信息(邮件预警)

直接上代码

python在学习阶段,存在多出冗余代码

应用场景
实时监控电脑本地系统运行情况,或某个进程
内存占用过大,指定时间内,进行邮件警示,发送信息于指定运维人员

流程 程序运行 --> 数据上传mysql数据库 --> 报表实时查看

效果图
在这里插入图片描述


import time
import psutil
import pymysql
import re
import threading
import os
import smtplib
import datetime
from email.header import Header
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.utils import parseaddr, formataddr
import configparser


def configparser_info():
    root_dir = os.getcwd()  # 获取当前文件所在目录路径
    cf = configparser.ConfigParser()
    cf.read(root_dir + "/config.ini",encoding='utf-8')  #防止中文乱码
    return cf



def mysql_info():
    #获取配置文件数据
    cf =configparser_info()

    # 配置数据库连接
    conn = pymysql.connect(
        host=cf.get("MySQL-Database", "host"),
        user=cf.get("MySQL-Database", "user"),
        password=cf.get("MySQL-Database", "password"),
        db=cf.get("MySQL-Database", "db"),
        charset=cf.get("MySQL-Database", "charset")
    )
    return conn



# 数据库连接配置
def mysql_insert(sql, data, table_name):
    # 配置数据库连接
    conn = mysql_info()
    # 创建游标对象
    cur = conn.cursor()
    # 判断数据表是否存在
    if table_exists(conn, cur, table_name) == 1:
        if table_name == 'email_conf':

            # 判断邮件配置表是否有数据
            cur.execute('SELECT COUNT(DISTINCT (CASE WHEN id IS NULL THEN 0 ELSE id END)) ids  FROM email_conf ')
            ids = cur.fetchall()

            # 如果邮件表里有数据,不进行数据插入
            if str(ids[0][0]) == '0':
                # 插入数据
                cur.execute(sql % data)
                conn.commit()
                print('成功插入', cur.rowcount, '条数据')
        else:
            # 插入数据
            cur.execute(sql % data)
            conn.commit()
            print('成功插入', cur.rowcount, '条数据')
    else:
        print('数据表不存在,请重新确定')




# 判断 数据库表是否存在
def table_exists(conn, cur, table_name):
    sql = "show tables;"
    cur.execute(sql)
    tables = cur.fetchall()

    table_list = re.findall('(\'.*?\')', str(tables))
    table_list = [re.sub("'", '', each) for each in table_list]
    if table_name in table_list:
        # 存在返回1
        return 1
    else:
        # (cpu_percent,memory_total, memory_available, memory_used,memory_percent,strftime)
        if table_name == 'cpu_info':
            sql = 'create table {}(' \
                  'id int(255) primary key not null auto_increment,' \
                  'cpu_percent float (6) comment "CPU使用信息",' \
                  'memory_total float (6) comment "内存总值(G)",' \
                  'memory_available float (6) comment "内存未使用值(G)",' \
                  'memory_used float (6) comment "内存使用值(G)",' \
                  'memory_percent float (6) comment "内存使用占比",' \
                  'strftime datetime comment "系统时间"' \
                  ')'.format(table_name)

            cur.execute(sql)
            conn.commit()
            return 1
        # (proc_id, status, memory_percent, stime, strftime)
        elif table_name == 'finebi_memory':
            sql = 'create table {}(' \
                  'id int(255) primary key not null auto_increment,' \
                  'proc_id int (10) comment "进程ID",' \
                  'status nvarchar (10) comment "进程状态",' \
                  'memory_percent float (6) comment "进程内存利用率",' \
                  'stime datetime comment "进程创建时间",' \
                  'strftime datetime comment "系统时间"' \
                  ')'.format(table_name)

            cur.execute(sql)
            conn.commit()
            return 1
        # (device, total, used, free, strftime)
        elif table_name == 'io_info':
            sql = 'create table {}(' \
                  'id int(255) primary key not null auto_increment,' \
                  'device nvarchar (10) comment "磁盘",' \
                  'total int (10) comment "总容量",' \
                  'used int (10) comment "已使用容量",' \
                  'free int(10) comment "可食用容量",' \
                  'strftime datetime comment "系统时间"' \
                  ')'.format(table_name)

            cur.execute(sql)
            conn.commit()
            return 1
        # data = (percent, etime, stime,  strftime)
        elif table_name == 'email_info':
            sql = 'create table {}(' \
                  'id int(255) primary key not null auto_increment,' \
                  'percent float comment "10分钟内 内存使用90%,占比",' \
                  'etime datetime comment "结束时间",' \
                  'stime datetime comment "开始时间",' \
                  'strftime datetime comment "发件时间",' \
                  'status int  comment "发件状态: 0.不在预警时间 ,1.发件成功 ,2.发件失败"' \
                  ')'.format(table_name)
            cur.execute(sql)
            conn.commit()
            return 1
        # (username, password, smtp_server, smtp_port,status, addressee)
        elif table_name == 'email_conf':
            sql = 'create table {}(' \
                  'id int(255) primary key not null auto_increment,' \
                  'username nvarchar (50) comment "发件人",' \
                  'password  nvarchar (50) comment "密码",' \
                  'smtp_server  nvarchar (50) comment "发件服务器",' \
                  'smtp_port  nvarchar (50) comment "发件端口",' \
                  'status int(5) comment "发件状态 : 1.使用  0.停用 ,初始化数据为 1",'\
                  'addressee  nvarchar (50) comment "收件人"' \
                  ')'.format(table_name)
            cur.execute(sql)
            conn.commit()
            return 1
        else:
            # 不存在返回0
            return 0


# 系统总内存 CPU占用情况
def cpu_info():
    while True:
        cpu_percent = psutil.cpu_percent()

        print('----------------------------------- CPU占用情况-------------------------------')

        # print('CPU完整信息', psutil.cpu_times());
        # print('CPU占用率', cpu_percent);

        nc = psutil.virtual_memory()

        memory_total = round(nc.total / 1024 / 1024 / 1024, 2)
        memory_available = round(nc.available / 1024 / 1024 / 1024, 2)
        memory_used = round(nc.used / 1024 / 1024 / 1024, 2)
        memory_percent = nc.percent
        strftime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))

        print('内存占用信息', nc)
        print('内存总值(G)', memory_total)
        print('内存未用值(G)', memory_available)
        print('内存使用值(G)', memory_used)
        print('内存占比', memory_percent)
        print('当前系统时间', strftime)

        print('  ')
        print('  ')

        table_name = 'cpu_info'
        sql = "INSERT INTO cpu_info (cpu_percent,memory_total, memory_available, memory_used,memory_percent,strftime) VALUES ( '%s', '%s', '%s', '%s','%s','%s' )"
        data = (cpu_percent, memory_total, memory_available, memory_used, memory_percent, strftime)

        # 调用mysql,执行逻辑
        mysql_insert(sql, data, table_name)
        # 执行 完成睡眠 30秒
        time.sleep(30)



# 进程 finebi.exe 内存占比
def finebi_memory():
    while True:
        for proc in psutil.process_iter():
            # 显示进程信息
            # print(proc)
            try:
                if proc.name() == 'finebi.exe':
                    p = psutil.Process(proc.pid)
                    # print(p)
                    print(p.memory_info())

                    strftime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                    proc_id = proc.pid
                    status = p.status()
                    memory_percent = round(p.memory_percent(), 2)
                    stime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(p.create_time()))
                    print('-----------------------------------finebi.exe 内存占比-------------------------------')
                    print('当前系统时间', strftime)
                    print('进程ID:', proc_id)
                    print('进程状态', status)
                    print('进程内存利用率', memory_percent)
                    print('进程创建时间', stime)

                    print('  ')
                    print('  ')

                    table_name = 'finebi_memory'
                    sql = "INSERT INTO finebi_memory (proc_id,status, memory_percent, stime,strftime) VALUES ( '%s', '%s', '%s', '%s','%s' )"
                    data = (proc_id, status, memory_percent, stime, strftime)
                    # 调用mysql,执行逻辑
                    mysql_insert(sql, data, table_name)


            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                # 进程未执行,不获取数据
                # table_name = 'finebi_memory'
                # sql = "INSERT INTO finebi_memory (proc_id,status, memory_percent, stime,strftime) VALUES ( '%s', '%s', '%s', '%s','%s' )"
                #
                # strftime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                # data = (0, 'kill', 0, strftime, strftime)
                # # 调用mysql,执行逻辑
                # mysql_insert(sql, data, table_name)
                pass
        # 执行 完成睡眠 30秒
        time.sleep(30)


# 系统磁盘占比
def io_info():
    while True:
        io = psutil.disk_partitions()

        print('------------------------------------系统磁盘----------------------------------------------------')
        print('')
        print('')
        print("系统磁盘信息:" + str(io))

        try:
            for i in io:
                o = psutil.disk_usage(i.device)
                device = i.device[0:1]
                total = int(o.total / (1024.0 * 1024.0 * 1024.0))
                used = int(o.used / (1024.0 * 1024.0 * 1024.0))
                free = int(o.free / (1024.0 * 1024.0 * 1024.0))
                strftime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
                print('磁盘:', device)
                print("总容量:", total)
                print("已用容量:", used)
                print("可用容量:", free)
                print('当前系统时间', strftime)

                table_name = 'io_info'
                sql = "INSERT INTO io_info (device,total, used, free,strftime) VALUES ( '%s', '%s', '%s', '%s','%s' )"
                data = (device, total, used, free, strftime)

                # 调用mysql,执行逻辑
                mysql_insert(sql, data, table_name)


        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess, PermissionError):
            pass
        #   ---------------------------------------------修改重新打包
        # 执行 完成睡眠 半小时
        time.sleep(60 * 30)




# 系统监控,进行邮件预警
def email_info():
    while True:
        conn = mysql_info()
        cur = conn.cursor()

        # 查询10分钟内内存使用占比,十分钟内如果系统内存使用量超过90 并且占比大于80% ,进行数据报警
        sql = 'SELECT ROUND(SUM(百分比)/COUNT(DISTINCT id),2)  占比,MAX(strftime) etime ,MIN(strftime) stime FROM ( SELECT id,strftime,IF(memory_percent > 90,1,0) 百分比 FROM cpu_info WHERE strftime >= DATE_ADD(NOW(), INTERVAL -10  MINUTE) ) a'
        # sql = 'SELECT ROUND(SUM(百分比)/COUNT(DISTINCT id),2)  占比,MAX(strftime) etime ,MIN(strftime) stime  FROM ( SELECT id,strftime,IF(memory_percent > 30,1,0) 百分比 FROM cpu_info  ORDER BY id  DESC  LIMIT 0,20 ) a'
        cur.execute(sql)
        result = cur.fetchall()

        try:
            for it in result:
                # 数据占比超过 80%
                if float(it[0]) >= 0.8:
                    percent = float(it[0])
                    etime = it[1]
                    stime = it[2]
                    print('-------------------------------内存预警-----------------------------------')
                    print('占比', percent)
                    print('结束时间', etime)
                    print('开始时间', stime)
                    strftime = datetime.datetime.now()
                    print('当前系统时间 ', strftime)

                    print('  ')
                    print('  ')
                    data = (percent, stime, etime)

                    #读取配置文件
                    cf = configparser_info()
                    stimes = datetime.datetime.strptime(str(datetime.datetime.now().date()) + cf.get("email_time","stime"), '%Y-%m-%d%H:%M')
                    etimes = datetime.datetime.strptime(str(datetime.datetime.now().date()) + cf.get("email_time","etime"), '%Y-%m-%d%H:%M')

                    # 判断当前时间是否在范围时间内
                    if strftime >= stimes and strftime <= etimes:
                        # 调用邮件发送
                        if int(send_report_mail(data)) == 1:
                            table_name = 'email_info'
                            sql = "INSERT INTO email_info (percent, etime, stime,  strftime,status) VALUES ( '%s', '%s', '%s', '%s' , '%s')"
                            datas = (percent, etime, stime, strftime, 1)
                            # 调用mysql,执行逻辑
                            mysql_insert(sql, datas, table_name)
                        else:
                            table_name = 'email_info'
                            sql = "INSERT INTO email_info (percent, etime, stime,  strftime,status) VALUES ( '%s', '%s', '%s', '%s' , '%s')"
                            datas = (percent, etime, stime, strftime, 2)
                            # 调用mysql,执行逻辑
                            mysql_insert(sql, datas, table_name)
                    else:
                        table_name = 'email_info'
                        sql = "INSERT INTO email_info (percent, etime, stime,  strftime,status) VALUES ( '%s', '%s', '%s', '%s' , '%s')"
                        datas = (percent, etime, stime, strftime, 0)
                        # 调用mysql,执行逻辑
                        mysql_insert(sql, datas, table_name)
        except  TypeError:
            pass
        # 执行 完成睡眠 10分钟
        time.sleep(60 * 10)



def _format_addr(s):
    """格式化邮件地址"""
    name, addr = parseaddr(s)
    return formataddr((Header(name, 'utf-8').encode(), addr))



def send_report_mail(data):
    percent = data[0]
    stime = data[1]
    etime = data[2]
    # 初始化邮件地址
    # 获取配置文件数据
    cf = configparser_info()
    # 账号密码
    username =cf.get("my_email", "username")
    password = cf.get("my_email", "password")
    # SMTP服务器地址
    smtp_server =cf.get("my_email", "smtp_server")
    smtp_port = cf.get("my_email", "smtp_port")
    # 收件人地址
    addressee = cf.get("my_email", "addressee")

    table_name = 'email_conf'
    sql = "INSERT INTO email_conf (username,password, smtp_server, smtp_port,status,addressee) VALUES ( '%s', '%s', '%s', '%s','%s','%s'  )"
    data = (username, password, smtp_server, smtp_port,1, addressee)
    # 调用mysql,执行逻辑,初始化邮件地址
    mysql_insert(sql, data, table_name)

    # 邮件预警
    try:
        # 读取邮件配置
        con1 = mysql_info()
        cur1 = con1.cursor()
        sql = '	SELECT *  FROM email_conf where status = 1'
        cur1.execute(sql)
        # 获取所有表数据
        results = cur1.fetchall()
        count = 0
        for it in results:
            usernames = it[1]
            passwords = it[2]
            smtp_servers = it[3]
            smtp_ports = it[4]
            addressees = it[6]
            # 初始化邮件对象
            msg = MIMEMultipart()
            msg['From'] = _format_addr("服务器运维 报表服务器246<%s>" % usernames)  # 邮件发件人
            msg['To'] = _format_addr('管理员 <%s>' % ','.join(addressees))  # 收件人地址
            msg['Subject'] = Header("报表服务器内存异常", 'utf-8').encode()  # 邮件主题

            text = '内存空间占用过大,请注意维护!!!' \
                   + '    内存占比   ' + str(percent) + '           ' \
                   + '    开始时间   ' + str(stime) + '        ' \
                   + '    结束时间   ' + str(etime) + '        '

            # 发送HTML文件
            msg.attach(MIMEText(text, 'html', 'utf-8'))
            # 括号中对应的是(SMTP服务器,端口)
            with smtplib.SMTP_SSL(smtp_servers, smtp_ports) as server:
                # 括号中对应的是(发件人邮箱账号、邮箱密码)
                server.login(usernames, passwords)
                # 括号中对应的是(发件人邮箱账号、收件人邮箱账号、发送邮件信息)
                server.sendmail(usernames, addressees, msg.as_string())
            count = count + 1


        if count > 0 and len(results) > 0:
            print("预警邮件成功发送!")
            return 1
        else :
            print("预警邮件发送失败!")
            return 0
    except smtplib.SMTPException as e:
        print("Error: 无法发送邮件 {}".format(e))
        return 0




if __name__ == '__main__':
    # 多线程执行多个方法
    threads = [threading.Thread(target=finebi_memory),
               threading.Thread(target=cpu_info),
               threading.Thread(target=io_info),
               threading.Thread(target=email_info)
               ]
    try:
        for t in threads:
            # 启动线程
            t.start()
        os.system("pause")
    except Exception as ex:
        print(ex)
        os.system("pause")


config.ini 配置文件

#注: 打包成EXE文件, 配置文件需要复制到EXE文件同目录下

#数据库信息配置
[MySQL-Database]
host=localhost
user=root
password=sumei15b
db=cpu
charset=utf8


#初始化邮件配置
#后面可以在数据库表中添加其它的邮件地址
[my_email]
username=*********@qq.com
password=wnotylenvmjogifd
# SMTP服务器地址
smtp_server=smtp.qq.com
smtp_port=465
# 收件人地址
addressee=*****@163.com


#邮件发送时间
#10分钟内,内存使用率90% 以上占比80%,进行邮件预警
[email_time]
stime=8:30
etime=18:00

数据表

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

打包运行

https://www.cnblogs.com/mini-monkey/p/11195309.html

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值