Linux服务器磁盘及内存用量监控Python脚本(推送钉钉群通知)

文章目录

Python 脚本

python 复制代码
# -*- coding: utf-8 -*-
import subprocess


def get_disk_usage():
    # 执行 df 命令获取磁盘使用情况
    df_process = subprocess.Popen(['df', '-h', '/'], stdout=subprocess.PIPE)
    output, _ = df_process.communicate()
    output = output.decode('utf-8')

    # 解析输出,获取磁盘总量和已使用占比
    total_space = None
    used_percentage = None
    lines = output.split('\n')
    for line in lines:
        if line.startswith('/dev'):
            parts = line.split()
            total_space = parts[1]
            used_percentage = parts[4]
            break
    print(f"磁盘总量: {total_space}, 已使用: {used_percentage}")
    return total_space, used_percentage


def check_disk_full(used_percentage, threshold_percent=90):
    # 检查磁盘是否快满了
    if used_percentage is not None:
        used_percentage = int(used_percentage[:-1])  # 去掉百分号并转换为整数
        if used_percentage >= threshold_percent:
            return True
    return False


def get_memory_usage():
    try:
        # 执行 free 命令获取内存信息
        free_process = subprocess.Popen(['free', '-h'], stdout=subprocess.PIPE)
        output, _ = free_process.communicate()
        output = output.decode('utf-8')
        # 解析输出,获取内存总量和已使用占比
        lines = output.split('\n')
        for line in lines:
            if line.startswith('Mem:'):
                parts = line.split()
                total_memory = parts[1]  # 内存总量
                used_memory = parts[2]   # 已使用内存
                print(f"内存总量: {total_memory}, 已使用: {used_memory}")
                return total_memory, used_memory
        return None, None
    except Exception as e:
        print(f"Error: {e}")
        return None, None


def check_memory_insufficient(total_memory, used_memory, threshold_percent=90):
    if total_memory is not None and used_memory is not None:
        # 解析内存值,去除单位,并将字符串转换为数值
        total_memory_value = float(total_memory[:-1])
        used_memory_value = float(used_memory[:-1])
        # 检查是否内存不足
        used_percentage = (used_memory_value / total_memory_value) * 100
        if used_percentage >= threshold_percent:
            return True
    return False


if __name__ == "__main__":
    # 获取磁盘使用情况
    total_space, used_percentage = get_disk_usage()
    if total_space and used_percentage:
        # 检查磁盘是否快满了(阈值默认为90%)
        if check_disk_full(used_percentage, threshold_percent=90):
            print("磁盘快满了!")
    else:
        print("未能获取磁盘使用情况。")

    # 获取内存使用情况
    total_memory, used_memory = get_memory_usage()
    if total_memory is not None and used_memory is not None:
        # 检查是否内存不足(默认阈值为90%)
        if check_memory_insufficient(total_memory, used_memory, threshold_percent=90):
            print("内存不足!")
    else:
        print("未能获取内存使用情况。")
  • 输出结果
bash 复制代码
磁盘总量: 36G, 已使用: 65%
内存总量: 4.7G, 已使用: 1.0G

钉钉推送通知

yml 复制代码
- ding-talk:
    secret: 'xxx'
    access-token: 'xxx'
- project:
    name: '项目名称'
    disk-threshold: 80
    memory-threshold: 90
  • Python
bash 复制代码
pip3 install pyyaml
pip3 install requests
python 复制代码
# -*- coding: utf-8 -*-
import subprocess
import yaml
import time
import hashlib
import base64
import hmac
import requests
from urllib.parse import quote
import socket


def get_disk_usage():
    # 执行 df 命令获取磁盘使用情况
    df_process = subprocess.Popen(['df', '-h', '/'], stdout=subprocess.PIPE)
    output, _ = df_process.communicate()
    output = output.decode('utf-8')

    # 解析输出,获取磁盘总量和已使用占比
    total_space = None
    used_percentage = None
    lines = output.split('\n')
    for line in lines:
        if line.startswith('/dev'):
            parts = line.split()
            total_space = parts[1]
            used_percentage = parts[4]
            break
    print(f"磁盘总量: {total_space}, 已使用: {used_percentage}")
    return total_space, used_percentage


def check_disk_full(used_percentage, threshold_percent=90):
    # 检查磁盘是否快满了
    if used_percentage is not None:
        used_percentage = int(used_percentage[:-1])  # 去掉百分号并转换为整数
        if used_percentage >= threshold_percent:
            return True
    return False


def get_memory_usage():
    try:
        # 执行 free 命令获取内存信息
        free_process = subprocess.Popen(['free', '-h'], stdout=subprocess.PIPE)
        output, _ = free_process.communicate()
        output = output.decode('utf-8')
        # 解析输出,获取内存总量和已使用占比
        lines = output.split('\n')
        for line in lines:
            if line.startswith('Mem:'):
                parts = line.split()
                total_memory = parts[1]  # 内存总量
                used_memory = parts[2]   # 已使用内存
                print(
                    f"内存总量: {total_memory}, 已使用: {used_memory}")
                return total_memory, used_memory
        return None, None
    except Exception as e:
        print(f"Error: {e}")
        return None, None


def check_memory_insufficient(total_memory, used_memory, threshold_percent=90):
    if total_memory is not None and used_memory is not None:
        # 解析内存值,去除单位,并将字符串转换为数值
        total_memory_value = float(total_memory[:-1])
        used_memory_value = float(used_memory[:-1])
        # 检查是否内存不足
        used_percentage = (used_memory_value / total_memory_value) * 100
        if used_percentage >= threshold_percent:
            return True
    return False


def read_yaml(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        try:
            data = yaml.safe_load(file)
            return data
        except yaml.YAMLError as e:
            print(f"读取 YAML 文件时出错:{e}")
            return None


def get_local_ip():
    try:
        # 创建一个 UDP 套接字
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.connect(('8.8.8.8', 80))  # 连接 Google DNS
        # 获取本地 IP 地址
        local_ip = sock.getsockname()[0]
        return local_ip
    except Exception as e:
        print(f"Error: {e}")
        return None


def dingTalkSign(dingTalkSecret):
    # 获取当前时间戳,并将其转换为毫秒级
    timestamp = int(time.time() * 1000)
    # 将时间戳和钉钉应用的密钥拼接在一起,将拼接后的字符串转换为字节数组
    signBefore = ('%s\n%s' % (timestamp, dingTalkSecret)).encode('utf-8')
    # 用HMAC-SHA256算法对字节数组进行签名
    hsha256 = hmac.new(dingTalkSecret.encode(
        'utf-8'), signBefore, hashlib.sha256)
    # 将签名进行Base64编码,将编码后的签名进行URL编码
    sign = quote(base64.b64encode(hsha256.digest()))
    return {"timestamp": timestamp, "sign": sign}


def sendMessage(dingTalkUrl='', dingTalkSecret=None, message='', atMobiles=[], isAtAll=False):
    print("发送内容:", message, atMobiles, isAtAll)
    json = {
        "msgtype": "text",
        "text": {
            "content": message,
        },
        "at": {
            "atMobiles": atMobiles,
            "isAtAll": isAtAll
        }
    }
    sign = dingTalkSign(dingTalkSecret)
    response = requests.post(url=dingTalkUrl, params=sign, json=json)
    print("响应内容:", response.json())


if __name__ == "__main__":
    local_ip = get_local_ip()
    file_data = read_yaml("config.yml")
    if file_data:
        for entry in file_data:
            if 'ding-talk' in entry:
                dingTalkSecret = entry['ding-talk']['secret']
                access_token = entry['ding-talk']['access-token']
                if dingTalkSecret is None:
                    print("未配置钉钉机器人密钥")
                if access_token is None:
                    print("未配置钉钉机器人Token")
                else:
                    # 自定义机器人推送地址
                    dingTalkUrl = f"https://oapi.dingtalk.com/robot/send?access_token={access_token}"
            if dingTalkSecret is not None and 'project' in entry:
                project_name = entry['project']['name']
                disk_threshold = entry['project']['disk-threshold']
                memory_threshold = entry['project']['memory-threshold']

                # 获取磁盘使用情况
                total_space, used_percentage = get_disk_usage()
                total_memory, used_memory = get_memory_usage()
                if (total_space and used_percentage) or (total_memory and used_memory):
                    # 检查磁盘是否快满了(阈值默认为90%)
                    if check_disk_full(used_percentage, threshold_percent=disk_threshold):
                        sendMessage(dingTalkSecret=dingTalkSecret, dingTalkUrl=dingTalkUrl, isAtAll=True,
                                    message=f'项目:{project_name}\n内网:{local_ip}\n磁盘:{total_space} / {used_percentage} (总/已用)\n内存:{total_memory} / {used_memory} (总/已用)\n磁盘不足,请及时扩容!')
                    # 检查是否内存不足(默认阈值为90%)
                    if check_memory_insufficient(total_memory, used_memory, threshold_percent=memory_threshold):
                        sendMessage(dingTalkSecret=dingTalkSecret, dingTalkUrl=dingTalkUrl, isAtAll=True,
                                    message=f'项目:{project_name}\n内网:{local_ip}\n磁盘:{total_space} / {used_percentage} (总/已用)\n内存:{total_memory} / {used_memory} (总/已用)\n内存不足,请及时扩容!')
                else:
                    print("未能获取磁盘使用情况。")

定时任务

bash 复制代码
# 查看python3安装位置
which python3
# 添加定时任务
crontab -e
bash 复制代码
# 定时执行Python脚本,根据自己需求配置执行时间
20 9 * * * /usr/bin/python3 /u01/setup.py
相关推荐
笨鸟笃行4 分钟前
爬虫第七篇数据爬取及解析
开发语言·爬虫·python
java1234_小锋10 分钟前
一周学会Flask3 Python Web开发-response响应格式
开发语言·python·flask·flask3
大数据追光猿11 分钟前
Python中的Flask深入认知&搭建前端页面?
前端·css·python·前端框架·flask·html5
java1234_小锋12 分钟前
一周学会Flask3 Python Web开发-flask3模块化blueprint配置
开发语言·python·flask·flask3
莫忘初心丶14 分钟前
python flask 使用教程 快速搭建一个 Web 应用
前端·python·flask
ChinaRainbowSea35 分钟前
1. Linux下 MySQL 的详细安装与使用
linux·数据库·sql·mysql·adb
不爱学英文的码字机器1 小时前
Python爬虫实战:从零到一构建数据采集系统
开发语言·爬虫·python
鹿鸣悠悠1 小时前
Python 类和对象详解
开发语言·python
laocooon5238578861 小时前
用Python实现的双向链表类,包含了头插、尾插、归并排序等功能
开发语言·python
网络安全(华哥)1 小时前
网络安全服务实施流程管理 网络安全服务体系
运维·服务器·网络