如何在Consul watch触发的健康检查脚本中获取故障服务名称
Consul Watch 触发脚本获取故障服务名的实现方法
核心机制
Consul Watch 匹配到对应监控事件、触发外部脚本执行时,不会将事件数据作为命令行位置参数传递给脚本,会把完整的匹配结果以结构化JSON格式,通过标准输入(stdin)流传给待执行的脚本,脚本只需要读取stdin内容做解析即可拿到对应服务信息。
具体实现步骤
- 修改health.sh脚本内容,第一步先完整读取stdin的所有内容,存入临时变量避免重复读取时内容丢失,核心读取语句为
watch_payload=$(cat) - 借助轻量JSON解析工具
jq提取字段:针对-type=checks类型的监控,返回的JSON是检查对象数组,每个检查对象中包含的核心字段:ServiceName: 关联的服务名称Status: 当前健康检查的状态(passing/warning/critical)Output: 检查的具体输出详情Node: 检查所在的节点名称
- 可直接参考以下脚本示例实现:
#!/bin/bash # 一次性读取Consul Watch通过stdin传递的事件JSON watch_payload=$(cat) # 检查jq依赖是否存在 if ! command -v jq &> /dev/null; then echo "告警脚本缺少jq依赖,无法解析服务信息" exit 1 fi # 遍历所有触发的检查条目,提取服务名组装告警内容 alert_content=$(echo "$watch_payload" | jq -r '.[] | "节点: \(.Node) 故障服务: \(.ServiceName) 当前状态: \(.Status) 详情: \(.Output)"') # 后续可以在这里把alert_content的内容发送到告警渠道 echo "触发告警: $alert_content"
配置注意事项
- 原命令中
-state=passing的配置仅会匹配健康状态正常的检查事件,如果目标是捕获故障告警,需要将状态参数调整为-state=warning,critical,否则脚本只会在服务恢复健康时被触发,和故障告警的预期场景不符。 - 脚本需要提前配置可执行权限(
chmod +x /home/consul/health.sh),否则Consul Watch触发时会执行失败。 - 不要尝试通过
$1、$2这类位置参数读取事件数据,这类位置变量在Consul Watch的执行逻辑里不会填充监控相关内容,所有事件数据仅存在于stdin流中。
内容的提问来源于stack exchange,提问作者nyan-cat
相关产品推荐
相关产品推荐

