Uptime Kuma安装/定时通知脚本

Uptime Kuma可以添加的监控项包括HTTP(s)、TCP、HTTP(s)关键词、HTTP(s) JSON查询、Ping、DNS记录、推送、Docker容器运行时间、Steam游戏服务等常见网站运行参数。当服务器发生意外情况时,Uptime Kuma支持用户选择70多种通知服务,例如Telegram、Discord、Gotify、Slack、Pushover、电子邮件等,以便及时接收网站服务故障通知,帮助用户减少经济损失。

Uptime Kuma具有灵活高效的用户交互界面,用户可以根据需要隐藏或显示监控状态,并且可以使用网页标签功能对不同功能的网站进行分类,以便在特定时段关注高风险站点。此外,Uptime Kuma还提供多种语言支持,官方就提供了中文语言包。

Github地址: https://github.com/louislam/uptime-kuma

以下是Uptime Kuma支持的功能特性:

  • 监控类型 :支持监控 HTTP(s) / TCP / HTTP(s) 关键字 / HTTP(s) Json 查询 / Ping / DNS 记录 / Push / Steam 游戏服务器 / Docker 容器 / 数据库(SQL Server、PostgreSQL、MySQL、MongoDB、Redis 等)

  • 通知类型:支持 Telegram / Discord / Gotify / Slack / Pushover / Email / Webhook 等 90 多种通知方式

  • 检测间隔:支持最低 20 秒的检测间隔

  • 图表:支持以图表形式查看历史数据

    docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:1

定时通知脚本(需要python3.7以上版本):

Centos7升级python3.7:

步骤一 安装编译环境包:
复制代码
[root@localhost]# yum install gcc-c++ gcc make cmake zlib-devel bzip2-devel openssl-devel ncurse-devel libffi-devel -y
步骤二 在线下载python 3.7源码包
复制代码
[root@localhost]# cd  /mnt/
[root@localhost mnt]# wget https://mirrors.huaweicloud.com/python/3.7.2/Python-3.7.2.tar.xz
步骤三 解压并配置:
复制代码
#解压文件
[root@localhost mnt]# tar xvf Python-3.7.2.tar.xz
#进入python3.7.2目录
[root@localhost mnt]# cd Python-3.7.2
#创建目录
[root@localhost Python-3.7.2]# mkdir -p /usr/local/python3
#配置安装目录
[root@localhost Python-3.7.2]# ./configure --prefix=/usr/local/python3 --enable-optimizations
步骤四 编译及安装:
复制代码
[root@localhost Python-3.7.2]# make && make install
步骤五 更换系统默认python版本:

1、配置环境环境:创建新版本python和pip的软链接

复制代码
[root@localhost Python-3.7.2]# ln -s /usr/local/python3/bin/python3.7 /usr/bin/python3
[root@localhost Python-3.7.2]# ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3

2、查看python版本

复制代码
[root@localhost Python-3.7.2]# python3 -V
Python 3.7.2
[root@localhost Python-3.7.2]# pip3 -V
pip 18.1 from /usr/local/python3/lib/python3.7/site-packages/pip (python 3.7)
步骤六 上传脚本、安装脚本所需python库:
复制代码
pip3 install uptime_kuma_api requests
步骤七 增加脚本执行权限:
复制代码
chmod +x cs.py
步骤八 降低url3库版本(如果openssl版本低于 1.1.1+ )解决报错:
复制代码
报错信息:
Traceback (most recent call last):
  File "cs_wgt.py", line 2, in <module>
    from uptime_kuma_api import UptimeKumaApi, MonitorStatus
  File "/usr/local/python3/lib/python3.7/site-packages/uptime_kuma_api/__init__.py", line 12, in <module>
    from .api import UptimeKumaApi
  File "/usr/local/python3/lib/python3.7/site-packages/uptime_kuma_api/api.py", line 12, in <module>
    import requests
  File "/usr/local/python3/lib/python3.7/site-packages/requests/__init__.py", line 43, in <module>
    import urllib3
  File "/usr/local/python3/lib/python3.7/site-packages/urllib3/__init__.py", line 42, in <module>
    "urllib3 v2.0 only supports OpenSSL 1.1.1+, currently "
ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled th 'OpenSSL 1.0.2k-fips  26 Jan 2017'. See: https://github.com/urllib3/urllib3/issues/2168

# 1. 查看当前urllib3版本(确认是v2.0+)
pip3 show urllib3

# 2. 卸载高版本urllib3
pip3 uninstall urllib3 -y

# 3. 安装兼容OpenSSL 1.0.2的版本(1.26.16是稳定兼容版)
pip3 install urllib3==1.26.16

# 4. 验证安装结果
pip3 show urllib3 | grep Version  # 输出应为1.26.16

步骤九:通过 crontab 设置定时启动脚本

crontab -e编辑界面中,添加一行对应你的定时需求,示例如下:

复制代码
# 示例1:每5分钟执行一次Python脚本(指定解释器+脚本绝对路径),并记录日志
*/5 * * * * /usr/bin/python3 /home/cs.py >> /home/cs_logs.log 2>&1

# 示例2:每天凌晨3点整执行脚本(已添加shebang和执行权限,直接执行脚本)
0 3 * * * /home/cs.py >> /home/cs.log 2>&1

# 示例3:每周日晚上8点(20点)执行脚本
0 20 * * 0 /usr/bin/python3 /home/cs.py >> /home/cs.log 2>&1

# 示例4:每月1号和15号的中午12点30分执行脚本
30 12 1,15 * * /usr/bin/python3 /home/cs.py >> /home/cs.log 2>&1

#编辑 / 创建定时任务
crontab -e

#查看当前定时任务
crontab -l

#查看crond服务状态
systemctl status crond

#启动crond服务
systemctl start crond

#设置crond服务开机自启
systemctl enable crond

#重启crond服务(修改定时任务后可选,一般无需重启,cron会自动加载新任务)
systemctl restart crond

附件:脚本详情:cs.py

复制代码
#!/usr/bin/python3
from uptime_kuma_api import UptimeKumaApi, MonitorStatus
import requests
import time
import hmac
import hashlib
import base64
import json
import urllib.parse
from datetime import datetime  # 处理当前时间

def get_dingtalk_sign(secret):
    """生成钉钉机器人签名(有密钥时使用)"""
    timestamp = str(round(time.time() * 1000))
    secret_enc = secret.encode('utf-8')
    string_to_sign = f'{timestamp}\n{secret}'
    string_to_sign_enc = string_to_sign.encode('utf-8')
    hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
    sign = urllib.parse.quote_plus(base64.b64encode(hmac_code).decode('utf-8'))
    return timestamp, sign

def send_dingtalk_notification(webhook, secret, monitor_info):
    """发送钉钉通知(兼容UP/DOWN状态,文案区分正常/异常)"""
    # 1. 签名处理(有密钥时拼接)
    if secret:
        timestamp, sign = get_dingtalk_sign(secret)
        webhook = f"{webhook}&timestamp={timestamp}&sign={sign}"

    # 2. 核心:根据实时状态区分文案
    realtime_status = monitor_info['realtime_status_name']
    if realtime_status == "UP":
        status_tag = "✅ 正常"
        availability = "📊 服务可用"
        tips = "✅ 该监控项状态正常"
        title_prefix = "📢"  # 正常通知前缀
    elif realtime_status == "DOWN":
        status_tag = "❌ 异常"
        availability = "📊 服务不可用"
        tips = "🚨 该监控项状态异常,请及时排查!"
        title_prefix = "⚠️"  # 异常通知前缀
    else:
        status_tag = "⚠️ 未知"
        availability = "📊 状态未知"
        tips = "⚠️ 该监控项状态未知,请核查!"
        title_prefix = "🔍"

    # 3. 格式化当前时间(最后检查时间)
    current_check_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    # 监控地址友好化
    monitor_url = monitor_info['url'] if monitor_info['url'] != "无URL" else "🔗 无监控地址"

    # 4. 单表格排版(无多余分段,钉钉渲染更美观)
    msg_template = {
        "msgtype": "markdown",
        "markdown": {
            "title": f"{title_prefix} Uptime Kuma监控通知 - {monitor_info['name']}",
            "text": f"""### {title_prefix} Uptime Kuma监控状态通知

| 监控项         | 详情                     |
|----------------|--------------------------|
| 监控名称       | {monitor_info['name']}    |
| 监控类型       | {monitor_info['type']}    |
| 监控目标       | {monitor_url}            |
| 实时状态       | {realtime_status}({status_tag}) |
| 最后检查时间   | 🕒 {current_check_time}   |
| 服务可用性     | {availability}           |

> {tips}
"""
        },
        "at": {
            "isAtAll": False  # 如需@所有人,改为True
        }
    }

    # 5. 发送请求并处理结果
    try:
        response = requests.post(
            url=webhook,
            headers={"Content-Type": "application/json;charset=utf-8"},
            data=json.dumps(msg_template),
            timeout=10
        )
        result = response.json()
        if result.get("errcode") == 0:
            print(f"✅ 钉钉通知发送成功:监控ID {monitor_info['id']}(状态:{realtime_status})")
            return True
        else:
            print(f"❌ 钉钉通知发送失败(监控ID {monitor_info['id']}):{result.get('errmsg')}")
            return False
    except Exception as e:
        print(f"❌ 钉钉通知发送异常(监控ID {monitor_info['id']}):{str(e)}")
        return False

def get_uptime_kuma_monitors(kuma_url, username, password, dingtalk_webhook=None, dingtalk_secret=None, monitor_ids=None):
    """
    核心逻辑:
    - 获取指定的监控项(通过monitor_ids参数),若不指定则获取所有
    - 严格区分UP(正常)/DOWN(异常)/未知状态的文案
    """
    api = UptimeKumaApi(kuma_url)
    all_monitors_to_notify = []  # 存储需要通知的监控项
    # 默认为空列表,若未指定则获取所有监控项
    monitor_ids = monitor_ids or []

    try:
        # 1. 登录Uptime Kuma
        api.login(username, password)
        print(f"✅ 成功登录Uptime Kuma实例:{kuma_url}")
        
        # 2. 获取监控项(指定ID或所有)
        all_monitors = []
        if monitor_ids:
            # 获取指定ID的监控项
            print(f"📌 开始获取指定的 {len(monitor_ids)} 个监控项...")
            for monitor_id in monitor_ids:
                try:
                    monitor = api.get_monitor(monitor_id)
                    all_monitors.append(monitor)
                    print(f"✅ 成功获取监控项 ID: {monitor_id}")
                except Exception as e:
                    print(f"❌ 获取监控项 ID: {monitor_id} 失败:{str(e)}")
        else:
            # 获取所有监控项
            all_monitors = api.get_monitors()
            print(f"📌 共获取到 {len(all_monitors)} 个监控项")

        # 3. 遍历处理每个监控项
        for monitor in all_monitors:
            # 基础字段容错获取
            monitor_id = monitor.get("id", "未知ID")
            monitor_name = monitor.get("name", "未知名称")
            monitor_url = monitor.get("url", "无URL")
            monitor_type = monitor.get("type", "未知类型")

            # 4. 获取实时状态(核心判断依据)
            realtime_status_name = "未知"
            try:
                if monitor_id != "未知ID":
                    rt_result = api.get_monitor_status(monitor_id)
                    # 兼容API返回的两种格式(枚举/字典)
                    if isinstance(rt_result, MonitorStatus):
                        realtime_status_name = rt_result.name
                    elif isinstance(rt_result, dict):
                        realtime_status_name = rt_result.get("status_name", "未知")
            except Exception as e:
                print(f"⚠️  监控ID {monitor_id} 实时状态查询失败:{str(e)}")

            # 5. 控制台打印监控信息
            print(f"\n监控ID: {monitor_id}")
            print(f"监控名称: {monitor_name}")
            print(f"实时状态: {realtime_status_name} → {'正常' if realtime_status_name == 'UP' else '异常' if realtime_status_name == 'DOWN' else '未知'}")
            print("-" * 60)

            # 6. 收集所有有效监控项(排除未知ID),用于发送通知
            if monitor_id != "未知ID":
                all_monitors_to_notify.append({
                    "id": monitor_id,
                    "name": monitor_name,
                    "url": monitor_url,
                    "type": monitor_type,
                    "realtime_status_name": realtime_status_name
                })

        # 7. 发送钉钉通知(所有有效监控项,无论UP/DOWN)
        if dingtalk_webhook and all_monitors_to_notify:
            print(f"\n📢 开始向钉钉发送 {len(all_monitors_to_notify)} 个监控项的状态通知...")
            for monitor in all_monitors_to_notify:
                send_dingtalk_notification(dingtalk_webhook, dingtalk_secret, monitor)

        return all_monitors_to_notify

    except Exception as e:
        print(f"❌ 获取监控信息失败:{str(e)}")
        import traceback
        traceback.print_exc()
        return []

    finally:
        # 8. 确保登出连接
        try:
            api.logout()
            print("\n✅ 已登出Uptime Kuma API连接")
        except Exception as e:
            print(f"⚠️  登出Uptime Kuma失败:{str(e)}")

# ------------------- 调用示例 -------------------
if __name__ == "__main__":
    # Uptime Kuma配置(替换为你的实际信息)
    KUMA_URL = "http://127.0.0.1:3001/"
    KUMA_USERNAME = "********"
    KUMA_PASSWORD = "********"
    
    # 钉钉机器人配置(替换为你的实际信息)
    DINGTALK_WEBHOOK = "**************************"
    DINGTALK_SECRET = "***************************"  
    # 无密钥则传None
    
    # 指定需要监控的ID列表,若为空则获取所有
    # 例如:获取ID为1和2的监控项 → [1, 2]
    # 只获取ID为3的监控项 → [3]
    # 获取所有监控项 → [] 或不传递该参数
    TARGET_MONITOR_IDS = [2, 3]  # 这里修改为你需要的监控项ID
    
    # 执行监控并发送通知
    get_uptime_kuma_monitors(
        kuma_url=KUMA_URL,
        username=KUMA_USERNAME,
        password=KUMA_PASSWORD,
        dingtalk_webhook=DINGTALK_WEBHOOK,
        dingtalk_secret=DINGTALK_SECRET,
        monitor_ids=TARGET_MONITOR_IDS  # 传递指定的监控项ID列表
    )
相关推荐
宇钶宇夕1 小时前
CoDeSys入门实战一起学习(十):CoDeSys库文件详解——从零搭建CoDeSys自定义库
运维·自动化·软件工程
Guheyunyi1 小时前
节能降耗管理系统:从静态优化到动态能源寻优的技术演进
大数据·人工智能·科技·安全·架构·能源
fpcc1 小时前
跟我学C++中级篇——文件和目录
linux·c++
leo03081 小时前
Ubuntu (NVIDIA Jetson) 开启 Wi-Fi 后系统高延迟、Ping 不通甚至硬死机排查全过程
linux·运维·ubuntu
济6171 小时前
linux 系统移植(第八期)----Linux 内核的获取、编译、顶层 Makefile 的简介-- Ubuntu20.04
linux
Ha_To2 小时前
2026.1.16 Linux磁盘实验
linux·运维·服务器
2023自学中2 小时前
嵌入式系统中的非易失性存储设备
linux·嵌入式硬件
2501_941982052 小时前
企业微信自动化:精准推送技术揭秘
运维·自动化·企业微信
历程里程碑2 小时前
Linux 1 指令(1)入门:6大基础指令详解
linux·运维·服务器·c语言·开发语言·数据结构·c++