python
from flask import Flask, request, jsonify
import requests
import logging
import threading
# 初始化日志与 Flask 实例
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger("CloudCanalFlaskReceiver")
app = Flask(__name__)
# 如果需要将告警进行二次分发,在此填入对应的群机器人 Webhook 地址
FORWARD_WEBHOOK_URL = "https://webhook-notification.com?groupId=xxx"
headers = {
# 模拟真实 Chrome 浏览器访问
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
def send_to_im_group_sync(summary_text):
"""
使用线程在后台异步发送请求,避免阻塞 Flask 的响应
"""
payload = {
"title":"cloudcanal告警",
"message":f"{summary_text}",
"openUrl":""
}
try:
response = requests.post(FORWARD_WEBHOOK_URL, json=payload, headers=headers,timeout=50)
logger.info(f"转发通知成功,响应码: {response.status_code}")
except Exception as e:
logger.error(f"转发通知失败: {str(e)}")
@app.route("/webhook/alert", methods=["POST"])
def receive_cloudcanal_alert():
try:
# 获取 JSON 数据
payload = request.json or {}
logger.info(f"收到 CloudCanal 告警数据: {payload}")
# 解析字段
task_name = payload.get("taskName") or payload.get("task_name") or "未知任务"
task_id = payload.get("taskId") or payload.get("task_id") or "N/A"
alert_msg = payload.get("alertMessage") or payload.get("message") or str(payload)
alert_level = payload.get("alertLevel") or "WARNING"
summary = (
f"任务名称: {task_name}\n"
f"任务 ID: {task_id}\n"
f"告警级别: {alert_level}\n"
f"详细信息: {alert_msg}"
)
logger.warning(f"🚨 解析到告警事件:\n{summary}")
# 使用多线程后台发送,防止请求阻塞
threading.Thread(target=send_to_im_group_sync, args=(alert_msg,)).start()
return jsonify({"status": "success", "message": "Alert received"}), 200
except Exception as e:
logger.error(f"解析 Webhook 请求失败: {str(e)}")
return jsonify({"status": "error", "message": str(e)}), 400
if __name__ == "__main__":
# 启动 Flask 服务,监听 8000 端口
app.run(host="0.0.0.0", port=8888)