实用工具:实时监控服务器CPU负载状态并邮件通知并启用开机自启

 作用:在服务器CPU高负载时发送邮件通知

目录

一、功能代码

二、配置开机自启动该监控脚本

1,配置自启脚本

2,启动

三、功能测试


一、功能代码

功能:在CPU负载超过预设置的90%阈值时就发送邮件通知!邮件内容显示服务器的公网IP、CPU逻辑核心数及每个逻辑核心数的负载详情

import psutil
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import requests
import time

# 阈值设置
threshold = 90

# 邮件服务器配置
smtp_server = 'smtp.qq.com'
smtp_port = 587  # QQ邮箱的端口号为587
# 发送方邮箱账号和密码
sender_email = 'xxxxxxx@qq.com'
sender_password = 'yxamfeswlsnijaie'
# 接收方邮箱地址
receiver_email = 'xxxxx@qq.com'

# 全局变量
cpu_usage = None  # 每个逻辑处理器的负载


def get_server_ip():
    server_ip = '未获取到公网ip'
    try:
        response1 = requests.get('https://ip.3322.net/', timeout=5)
        if response1.text:
            server_ip = response1.text
    except:
        pass
    try:
        response2 = requests.get('https://myip.ipip.net', timeout=5)
        if response2.text:
            unformat_server_ip = response2.text
            server_ip = unformat_server_ip.split(':')[1]
    except:
        pass
    try:
        response3 = requests.get('https://ddns.oray.com/checkip', timeout=5)
        if response3.text:
            unformat_server_ip = response3.text
            server_ip = unformat_server_ip.split(':')[1]
    except:
        pass
    return server_ip


# 监测CPU负载并发送邮件通知
def monitor_cpu_load():
    # 初始化标志变量
    last_email_sent = None

    while True:
        global cpu_usage
        time.sleep(3)  # 这里睡眠3秒是因为服务器在重启开机时的瞬间cpu负载是比较高的,所以并不准确,等待3秒更准确
        cpu_usage = psutil.cpu_percent(interval=1, percpu=True)  # 每个逻辑处理器的负载

        if all(usage >= threshold for usage in cpu_usage) and last_email_sent != "high":
            subject = "CPU负载过高警告"
            body = '服务器公网IP:{0}\n CPU逻辑核心数:{1}\n CPU每个逻辑核心负载均已超90%,请登录服务器查看详情\n CPU核心负载详情:\n'
            send_email(subject, body)
            last_email_sent = "high"
        elif all(usage < threshold for usage in cpu_usage) and last_email_sent != "normal":
            subject = "CPU负载恢复正常通知"
            body = '服务器公网IP:{0}\n CPU逻辑核心数:{1}\n CPU已恢复正常。\n CPU核心负载详情:\n'
            send_email(subject, body)
            last_email_sent = "normal"


# 发送邮件通知
def send_email(subject, body):
    # 创建邮件内容
    global cpu_usage
    cpu_count = psutil.cpu_count(logical=True)  # cpu逻辑核心数
    server_ip = get_server_ip()  # 获取公网ip
    for i in range(cpu_count):
        body += "\t{%d}%%\n" % (i + 2)
    body = body.format(server_ip, cpu_count, *cpu_usage)

    message = MIMEMultipart()
    message['From'] = sender_email
    message['To'] = receiver_email
    message['Subject'] = subject

    # 添加邮件正文
    # MIMEText有三个参数第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码可不填
    message.attach(MIMEText(body, 'plain'))
    # 发送邮件
    try:
        print("正在发送邮件...")
        smtp = smtplib.SMTP(smtp_server, smtp_port)
        smtp.starttls()  # 开启TLS加密连接
        smtp.login(sender_email, sender_password)
        smtp.sendmail(sender_email, receiver_email, message.as_string())
        print("邮件发送成功!")
    except smtplib.SMTPException as e:
        print("邮件发送失败:", e)
    finally:
        print("正在退出")
        smtp.quit()


if __name__ == "__main__":
    monitor_cpu_load()

sender_email和receiver_email 填写自己的邮箱地址

sender_password 是登录QQ邮箱的授权码

详情参考:https://itutd.blog.csdn.net/article/details/131810368?spm=1001.2014.3001.5502

二、配置开机自启动该监控脚本

1,配置自启脚本

在服务器/usr/lib/systemd/system目录下创建一个新的.service文件

vi /usr/lib/systemd/system/autorun_python.service

写入以下内容

[Unit]
Description=python_script - monitor cpu
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=simple
ExecStart=/root/.virtualenvs/qubian/bin/python3 /home/monitor_cpu.py
Restart=always
[Install]
WantedBy=multi-user.target

 修改配置后可能需要运行以下命令重新加载

systemctl daemon-reload

 参数解释:

  1. [Unit]:这个部分主要用于定义服务单元的基本信息,包括服务的描述和启动顺序等。

    • Description:描述这个服务的作用,通常是一个简短的描述。
    • After:指定在启动这个服务之前需要先启动的其他服务单元。在本例中,指定了在启动这个服务之前需要先启动的服务有 network.targetremote-fs.target 和 nss-lookup.target
  2. [Service]:这个部分定义了服务运行时的相关参数。

    • Type:指定服务的类型,有 simple、forking、oneshot、dbus、notify 等类型。在这里,Type=simple 表示这是一个简单类型的服务。
    • ExecStart:定义服务启动时执行的命令或脚本。在这个例子中,指定了使用指定的 Python 虚拟环境中的 Python 解释器执行 /home/monitor_cpu.py 脚本。
    • Restart:指定服务异常退出时的重启策略,always 表示始终重启。
  3. [Install]:指定服务的安装相关信息。

    • WantedBy:指定服务所属的 target,即服务启动的目标。在这里,multi-user.target 表示这个服务是为了多用户模式下运行的。

对于Type参数的值有以下:

  1. Type=forking:表示服务将以分叉(forking)方式运行,即服务会创建一个子进程来运行主要的服务进程。当主进程退出时,服务就会被认为是已经停止。但是,它还支持在主进程退出后,Systemd会等待一段时间,以便子进程可以执行一些清理工作。

  2. Type=simple:它表示这个服务是一个简单的服务,即它只有一个主进程,当这个主进程退出时,服务就会被认为是已经停止。

  3. Type=oneshot:这种类型的服务是指它只需要在启动时运行一次。当主进程退出时,服务就会被认为是已经停止。

  4. Type=dbus:这种类型的服务是指它需要一个D-Bus名称,以便Systemd可以监控它。

  5. Type=notify:这种类型的服务是指它会在主进程准备好接受请求时,发送一个通知给Systemd。当Systemd接收到这个通知时,它就会认为服务已经启动。

  6. Type=idle:这种类型的服务是指它会在所有其他类型的服务都已经启动后,才会启动。

2,启动
# 设置开机自启动
systemctl enable autorun_python.service
# 运行服务
systemctl start autorun_python.service
# 查看服务运行状态 
systemctl status autorun_python.service

 查看服务运行状态,显示active(running)正在运行中...

更多相关命令

# 关闭开机自启
systemctl disable autorun_python.service
# 停止运行服务
systemctl stop autorun_python.service
# 重启服务
systemctl restart autorun_python.service

三、功能测试

写一个让CPU满载的程序测试上面监控CPU的代码功能是否能正常工作

from multiprocessing import cpu_count
from multiprocessing import Process


def func():  # 死循环函数,让cpu满载
    while True:
         pass


if __name__ == '__main__':
    p_lst = []  # 定义一个列表
    core_count = cpu_count()  # CPU核心数
    for i in range(core_count):
        p = Process(target=func)  # 子进程调用函数
        p.start()  # 启动子进程
        p_lst.append(p)  # 将所有进程写入列表中
    for p in p_lst:
        p.join()  # 检测p是否结束,如果没有结束就阻塞直到结束,否则不阻塞
    print('结束')

使用htop命令查看cpu的负载状态

 这时四个核心全被干满了!

也收到了超负载的邮件通知

当CPU负载恢复正常时也收到了相应的邮件

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/425395.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

求阶乘。。

&#xff01;&#xff01;&#xff01;答案解释摘录自蓝桥云课题解 问题描述 满足N!的末尾恰好有个0的最小的N是多少? 如果这样的N不存在输出-1。 输入格式 一个整数 K 输出格式 一个整数代表答案 样例输入 2 样例输出 10 import os import sys# 请在此输入您的代码 def coun…

懒人必备|视频号片段提取实战教程!

你是否也为如何提取视频号的视频感到困扰&#xff1f;想要留住那些美好瞬间&#xff0c;但又不知道改如何操作&#xff1f;别瞎找了&#xff01;今天就让我来教你正确的步骤&#xff0c;让你轻松成为“提取达人”&#xff01; 首先&#xff0c;打开想要提取的视频&#xff0c;找…

某u盘 对比 sd卡+读卡器

部分 u盘 性能甚至不如 读卡器SD卡 电脑 支持USB3 gen2 的 USBA接口(u盘用) 和 typec接口(读卡器用) 极致性能需求可考虑: m.2固态硬盘盒m.2固态 设备 速度对比 迅雷... 拷贝文件信息 共用格式化信息

青少年软件编程(Python)等级考试试卷(一级)2020年3月

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;一级&#xff09;2020年3月 第 1 题 【单选题】 运行下方代码段&#xff0c;输出的是( )。 print("a"*3) A :a3 B :3a C :a a a D :aaa 正确答案:D 试题解析 第 2 题 【单选题】 下…

SpringBoot整合rabbitmq-重复消费问题

说明&#xff1a;重复消费的原因大致是生产者将信息A发送到队列中&#xff0c;消费者监听到消息A后开始处理业务&#xff0c;业务处理完成后&#xff0c;监听在告知rabbitmq消息A已经被消费完成途中中断&#xff0c;也就时说我已经处理完业务&#xff0c;而队列中还存在当前消息…

【C++】类的默认成员函数(上)

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、默认成员函数二、构造函数构造函数的概念及特性 三、析构函数析构函数的特性…

#QT(DEMO2-登录界面)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;DEMO登录 3.记录 Line Edit输入不换行 密码框输入如下设置: 运行效果 4.代码

使用Matplotlib绘制圆环图

圆环图是饼图的修改版&#xff0c;中间区域被切掉。圆环图更关注使用弧的面积来以最有效的方式表示信息&#xff0c;而不是饼图&#xff0c;饼图更关注比较切片之间的比例面积。圆环图在空间方面更有效&#xff0c;因为圆环图内部的空白空间可用于显示有关圆环图的一些附加信息…

【C++那些事儿】深入理解C++类与对象:从概念到实践(中)| 默认构造函数 | 拷贝构造函数 | 析构函数 | 运算符重载 | const成员函数

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C那些事儿 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 1. 类的6个默认成员函数2. 构造函数2.1 概念2.2 特性 3. 析构函数3.1 概念3.2 特性 4. 拷贝…

flutter 文字一行显示,超出换行

因为app有多语言&#xff0c;中文和其他语言长度不一致&#xff0c;可能导致英文会很长。 中文样式 英文样式 代码 Row(mainAxisAlignment: MainAxisAlignment.end,crossAxisAlignment: CrossAxisAlignment.end,children: [Visibility(visible: controller.info.fee ! null,ch…

产品经理岗位的任职资格和职业规划

产品经理主要是商业银行以客户为导向的&#xff0c;具体负责组织银行某一金融产品线的创新设计、生产营销和管理服务的工作。这类人士主要负责应用实施工作&#xff0c;其中产品线由一系列的产品构成&#xff0c;公司的产品经理主要分为全过程产品创新设计专家、全过程产品生产…

驾驭栈和队列,首先逃不开这些(有效括号、栈和队列相互模拟、循环队列)

一.有效括号 . - 力扣&#xff08;LeetCode&#xff09; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须…

力扣74. 搜索二维矩阵(二分查找)

Problem: 74. 搜索二维矩阵 文章目录 题目描述思路复杂度Code 题目描述 思路 思路1&#xff1a;映射为一维数组二分查找 1.由于题目矩阵中的元素整体是升序的&#xff0c;我们可以将其放置在一个大小为 m n m \times n mn的一维数组array中进行二分查找 2.对应的映射关系是ar…

微信小程序,h5端自适应登陆方式

微信小程序端只显示登陆(获取opid),h5端显示通过账户密码登陆 例如: 通过下面的变量控制: const isWeixin ref(false); // #ifdef MP-WEIXIN isWeixin.value true; // #endif

(C语言)qsort函数模拟实现

前言 我们需先了解qsort函数 qsort函数详解&#xff1a;http://t.csdnimg.cn/rTNv9 qsort函数可以排序多种数据类型&#xff0c;很是神奇&#xff0c;这是为什么&#xff0c;我们在里模拟实现这样的功能 目录 1. qsort函数模拟实现 2. 我们使用bubble_sort函数排序整形数…

ruoyi 图片等文件资源读取

老是忘&#xff0c;记录一下 ResourcesConfig 文件下 /** 本地文件上传路径 */ registry.addResourceHandler(Constants.RESOURCE_PREFIX "/**").addResourceLocations("file:" RuoYiConfig.getProfile() "/"); /*** 资源映射路径 前缀*/ …

【Web安全靶场】xss-labs-master 1-20

xss-labs-master 其他靶场见专栏 文章目录 xss-labs-masterlevel-1level-2level-3level-4level-5level-6level-7level-8level-9level-10level-11level-12level-13level-14level-15level-16level-17level-18level-19level-20 level-1 第一关没有进行任何限制&#xff0c;get请求…

python复盘(1)

1、变量名的命名规则 #3、变量名的命名规则&#xff1a;可以用中文作为变量名&#xff1b;其他和go语言一样 # 变量名可以用数字、字母、下划线组成&#xff0c;但是数字不能作为开头 # 变量名不能使用空格&#xff0c;不能使用函数名或关键字 # 变量名最好能表示出他的作用2、…

Qt/事件分发器/事件过滤器

事件分发器 //事件分发器bool event(QEvent* e); //事件分发器&#xff1a;&#xff1a;用途 分发事件 bool MyLabel::event(QEvent* e) {if(e->type() QEvent::MouseButtonPress){//如果是鼠标摁下 拦截事件 不向下分发QMouseEvent* ev static_cast<QMouseEvent*>…

python类型注解,多态详解

目录 1.类型注解 1.变量的类型注解 2.函数&#xff08;方法&#xff09;的类型注解 3.union类型 2.多态 抽象类 1.类型注解 1.变量的类型注解 #基础数据类型注解 import randomv1 : int 10 v2 : str "aaa" v3 : bool True#类对象类型注解 class student:p…