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}×tamp={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列表
)