当前位置: 首页 > news >正文

用python解放右手(九) 机器人告警-让Python替你喊人

机器人告警:让 Python 替你"喊人"

本文基于 Python 3.9+,涉及:企业微信/钉钉 Webhook。阅读时间约 10 分钟。


周末的"静默灾难"

周六晚上,阿明正在家陪娃搭积木,手机突然响了。

是老板:“阿明,系统是不是挂了?客户说登不上。”

阿明心里一紧,打开 VPN 连公司内网,果然——数据库连接池满了,服务全崩了。

他花了两个小时抢修,恢复后一看日志——问题在周六凌晨 3 点就出现了,只是没人发现。

周一早上,阿明顶着黑眼圈到公司,被老板叫进办公室:“为什么周末出问题了没人知道?”

阿明委屈:“我在家带娃呢,不可能 24 小时盯着屏幕……”

"那就让系统自己’喊人’啊。"老板皱眉。

阿明找到老张:“张哥,系统出问题了,能自动发消息到微信/钉钉吗?”

老张:“能。让 Python 当你的’看门大爷’,出事了替你@所有人。”


第一步:认识 Webhook——机器人的"电话号码"

“阿明,你知道怎么让程序往微信群里发消息吗?”

“不知道……”

“用Webhook。你可以把它理解为机器人的’电话号码’——你往这个地址发一条 HTTP 请求,机器人就在群里喊一嗓子。”

老张在白纸上画了个图:

你的 Python 脚本 → 发送 HTTP POST 请求 → 企业微信/钉钉服务器 → 群里出现消息

“不需要登录微信,不需要扫码,只要一个 URL,就能发消息。”


第二步:企业微信机器人

“先教你企业微信的,钉钉类似。”

创建机器人

  1. 打开企业微信群聊
  2. 右键群设置 → 添加群机器人
  3. 选择【新建机器人】,取个名字(比如"告警小助手")
  4. 复制Webhook 地址

“Webhook 地址长这样:”

https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

“这个key就是机器人的身份标识,别泄露,不然别人也能往你们群里发消息。”

发送文本消息

importrequestsimportjson WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key"defsend_text(content,mentioned_list=None):"""发送文本消息到企业微信"""data={"msgtype":"text","text":{"content":content,"mentioned_list":mentioned_listor[],# @指定人}}response=requests.post(WEBHOOK_URL,data=json.dumps(data,ensure_ascii=False).encode("utf-8"),headers={"Content-Type":"application/json"})result=response.json()ifresult.get("errcode")==0:print("✅ 消息发送成功!")else:print(f"❌ 发送失败:{result}")# 测试发送send_text("🚨 告警测试:这是一条来自 Python 的消息")# @所有人send_text("🔥 系统异常!请立即处理!",mentioned_list=["@all"])

msgtype": "text"是发纯文本,mentioned_list可以 @指定人或 @所有人。”

阿明瞪眼:“就这么简单?”

“就这么简单。”


第三步:发送 Markdown 消息(更美观)

“纯文本太朴素了,咱们用 Markdown 格式,支持加粗、颜色、链接。”

defsend_markdown(content):"""发送 Markdown 消息"""data={"msgtype":"markdown","markdown":{"content":content}}response=requests.post(WEBHOOK_URL,data=json.dumps(data,ensure_ascii=False).encode("utf-8"),headers={"Content-Type":"application/json"})returnresponse.json()# 发送格式化的告警信息markdown_content="""## 🚨 系统告警 > **告警时间**: 2024-01-22 03:15:00 > **告警级别**: <font color='red'>严重</font> **异常信息**: - 服务: `user-service` - 错误: 数据库连接池耗尽 - 影响: 用户无法登录 **处理建议**: 1. 检查数据库连接数 2. 重启连接池 3. 查看慢查询日志 [点击查看详情](http://grafana.company.com/d/xxx) """send_markdown(markdown_content)

“企业微信的 Markdown 支持有限,但基本的加粗、颜色、链接都够用。”

<font color='red'>严重</font>是标红,让关键信息一眼看到。”


第四步:发送卡片消息(最专业)

“如果要发得像个正经告警系统,用卡片消息——带标题、内容、跳转链接。”

defsend_card(title,description,url,btntxt="查看详情"):"""发送文本卡片"""data={"msgtype":"textcard","textcard":{"title":title,"description":description,"url":url,"btntxt":btntxt}}response=requests.post(WEBHOOK_URL,data=json.dumps(data,ensure_ascii=False).encode("utf-8"),headers={"Content-Type":"application/json"})returnresponse.json()# 发送告警卡片send_card(title="🚨 数据库连接池告警",description="<div class=\"gray\">2024-01-22 03:15:00</div> <div class=\"normal\">服务: user-service</div><div class=\"highlight\">数据库连接数: 198/200 (99%)</div>",url="http://grafana.company.com/d/xxx",btntxt="立即查看")

“卡片消息在群里显示得很规整,点击按钮直接跳转到监控页面。”


第五步:钉钉机器人

“钉钉机器人的逻辑一模一样,只是 API 地址和格式略有不同。”

创建机器人

  1. 打开钉钉群 → 群设置 → 智能群助手
  2. 添加机器人 → 自定义(通过 Webhook 接入)
  3. 复制 Webhook 地址

发送消息

importrequestsimportjsonimporthmacimporthashlibimportbase64importurllib.parseimporttime DINGTALK_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=你的token"DINGTALK_SECRET="你的加签密钥"# 如果开启了加签defgenerate_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))returntimestamp,signdefsend_dingtalk_text(content,at_mobiles=None):"""发送钉钉文本消息"""timestamp,sign=generate_sign(DINGTALK_SECRET)url=f"{DINGTALK_WEBHOOK}&timestamp={timestamp}&sign={sign}"data={"msgtype":"text","text":{"content":content},"at":{"atMobiles":at_mobilesor[],"isAtAll":False}}response=requests.post(url,json=data)returnresponse.json()# 测试send_dingtalk_text("🚨 钉钉告警测试:系统异常,请处理!",at_mobiles=["13800138000"])

“钉钉如果开启了’加签’安全设置,需要额外计算签名。没开启的话,直接 POST 到 Webhook 地址就行。”


第六步:实战——异常自动告警

“来,把告警和异常处理结合起来,做一个真正能用的监控脚本。”

importrequestsimportjsonimportloggingfromdatetimeimportdatetime# 配置WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key"CHECK_URL="http://your-service.com/health"# 健康检查接口# 日志logging.basicConfig(filename="monitor.log",level=logging.INFO,format="%(asctime)s - %(message)s")defsend_alert(title,message,level="warning"):"""发送告警到企业微信"""color="red"iflevel=="critical"else"orange"iflevel=="warning"else"blue"markdown=f"""##{title}> **时间**:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}> **级别**: <font color='{color}'>{level.upper()}</font>{message}"""data={"msgtype":"markdown","markdown":{"content":markdown}}try:response=requests.post(WEBHOOK_URL,data=json.dumps(data,ensure_ascii=False).encode("utf-8"),headers={"Content-Type":"application/json"},timeout=10)logging.info(f"告警已发送:{title}")returnresponse.json()exceptExceptionase:logging.error(f"告警发送失败:{e}")returnNonedefcheck_service():"""检查服务状态"""try:response=requests.get(CHECK_URL,timeout=5)ifresponse.status_code!=200:send_alert(title="🚨 服务异常",message=f"健康检查返回非 200 状态码:{response.status_code}",level="critical")returnFalsedata=response.json()ifdata.get("status")!="ok":send_alert(title="⚠️ 服务告警",message=f"服务状态异常:{data}",level="warning")returnFalselogging.info("服务检查正常")returnTrueexceptrequests.exceptions.Timeout:send_alert(title="🚨 服务超时",message="健康检查请求超时,服务可能无响应",level="critical")returnFalseexceptExceptionase:send_alert(title="🚨 检查失败",message=f"健康检查异常:{str(e)}",level="critical")returnFalse# 执行检查if__name__=="__main__":print("🔍 开始服务检查...")check_service()

“这段代码干了啥?”

“1. 访问服务的健康检查接口
2. 如果状态码不是 200,或者返回内容异常,就发告警到企业微信
3. 捕获超时、异常等各种错误情况
4. 记录日志,方便事后排查”

“配合上一篇学的定时任务,你可以设每 5 分钟检查一次,出问题立刻在群里喊人。”


踩坑提醒:机器人告警的坑

坑 1:消息频率限制

“企业微信和钉钉都有频率限制,发太猛会被禁言。”

“企业微信:每个机器人最多 20 条/秒
钉钉:每个机器人最多 20 条/秒”

"解决办法:

  • 合并多条告警为一条
  • 加冷却时间(同样的错误 10 分钟内只报一次)
  • 分级告警:警告发邮件,严重才发群"

坑 2:Webhook 泄露

“Webhook 地址就是机器人的’钥匙’,泄露了别人就能往你们群里发消息。”

"解决办法:

  • 别把 Webhook 地址硬编码在代码里,放环境变量
  • 定期更换 Webhook
  • 开启 IP 白名单"
importos WEBHOOK_URL=os.environ.get("WECHAT_WEBHOOK_URL")

坑 3:网络不通

“公司内网可能访问不了外网的企业微信/钉钉服务器。”

"解决办法:

  • 用公司内网的 IM 系统
  • 配置代理
  • 或者用邮件告警做备选"

坑 4:告警风暴

“系统挂了,每分钟报一次警,群里 100 条消息,大家直接屏蔽群。”

"解决办法:

  • 同一个问题,5 分钟内只报一次
  • 恢复后发送’已恢复’通知
  • 汇总告警:把同类问题合并成一条"
# 简单的冷却机制last_alert_time={}defsend_alert_with_cooldown(alert_id,title,message,cooldown=300):"""带冷却的告警"""now=time.time()ifalert_idinlast_alert_time:ifnow-last_alert_time[alert_id]<cooldown:return# 冷却中,不发last_alert_time[alert_id]=now send_alert(title,message)

一句话总结

阿明把监控脚本部署到了服务器,设置了每 5 分钟检查一次。

周六凌晨 3 点,数据库连接池满了。3:05,企业微信群里弹出一条消息:

🚨服务异常
时间: 2024-01-22 03:05:00
级别:严重
服务状态异常,请立即处理!

值班同事被@醒,及时处理,避免了事故扩大。

周一,老板在群里说:“这个告警机制不错,推广到其他系统。”

阿明找到老张:“张哥,最后教我一招——怎么把这些全部串起来?”

老张笑了:“下篇,终极篇。”


扩展思考

"机器人告警的应用场景:

  • 系统监控:CPU/内存/磁盘超过阈值,自动告警
  • 业务监控:订单量突降、支付失败率升高,自动告警
  • 数据质量:ETL 任务失败、数据延迟,自动告警
  • 安全告警:异常登录、敏感操作,自动告警
  • 定时汇报:每天自动发送业务数据摘要到群

“核心逻辑:检测 → 判断 → 通知 → 记录。”


下集预告

下一篇,终极篇。老张带阿明把前面学的所有技能串起来——文件处理、Excel、邮件、定时任务、PDF、爬虫、可视化、机器人告警,打造一个完整的个人自动化工作流。阿明终于实现了"代码在跑,我在喝咖啡"。

记住:机器人告警就像看门大爷——平时睡觉(静默),有风吹草动立刻吹哨子(发消息)。你不需要亲自站岗,只需要告诉他"什么情况下吹哨子"。


你们公司用什么方式告警?邮件?微信?钉钉?还是靠人盯着?欢迎在评论区吐槽。

http://www.cnnetsun.cn/news/1975643.html

相关文章:

  • TranslucentTB终极修复指南:快速解决Microsoft.UI.Xaml依赖问题
  • BabelDOC:三步实现PDF智能翻译的终极指南
  • 实测有效!PyTorch 2.8镜像解决‘PackagesNotFoundError‘安装报错
  • 3分钟学会:零安装的SQLite在线查看器,浏览器直接管理数据库
  • UE5启动崩溃:从报错日志到精准修复的实战指南
  • 如何彻底修复Windows 11资源管理器崩溃问题:ExplorerPatcher终极指南
  • 抖音下载器完整指南:如何批量下载无水印视频和直播内容
  • 5G/6G毫米波系统设计避坑指南:信道建模中的RMS时延扩展与相干带宽到底怎么用?
  • 八大网盘直链解析工具:如何一键获取真实下载地址实现全速下载?
  • YMODEM协议在RT-Thread中的性能优化:从9600到115200波特率的传输速度对比
  • Prometheus常见监控指标Metrics(Prometheus指标)(Counter计数器、Gauge仪表盘、Histogram直方图、Summary摘要)时间序列
  • 从零散笔记到知识网络:Zotero Better Notes如何重塑学术工作流
  • Z-Image-GGUF提示词入门:‘主体+风格+光照+质量’四步法详解
  • 如何快速解密网易云音乐NCM文件:ncmdump完整指南
  • **发散创新:基于Python与ROS的机器人运动控制实战解析**在现代机器人系统开发
  • 保姆级教程:用STM32CubeMX配置MPU6050陀螺仪,5分钟搞定平衡小车姿态数据读取
  • VCS仿真dump fsdb波形踩坑实录:从$test$plusargs到UCLI的避坑指南
  • 零基础玩转JDY-31蓝牙模块:从硬件连接到参数配置的保姆级教程
  • 开源风扇控制方案:用Fan Control打造个性化静音散热系统
  • 5个步骤从零开始:用OBS StreamFX打造电影级直播画面
  • STM32 SAI接口实战:用CubeMX快速配置多通道音频采集(附DMA优化技巧)
  • sql_exporter配置避坑指南:手把手教你处理多表关联查询和动态标签(以用户订单分析为例)
  • 手把手推导:从面积等效原理到SVPWM发波,用几何图解代替复杂公式
  • 避开Matlab优化那些坑:fmincon参数设置、初始点选择与非线性约束函数编写避坑指南
  • Python的__get__、__set__、__delete__描述符协议完整实现
  • 避坑指南:开启Linux Framebuffer Console后系统卡住?排查LCD驱动里的这两个关键点
  • 别再傻傻等5秒了!实战中优化时间盲注效率的3个技巧(附Python脚本调优)
  • 【C++】中INI配置文件读取技术详解
  • ncmdump技术架构深度解析:网易云音乐加密文件转换机制
  • 番茄小说下载器:打造个人离线小说图书馆的终极解决方案