You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置Spinnaker阶段比较Prometheus指标并控制流水线执行

实现Prometheus指标对比并触发CI阶段失败的方案

一、Bash Script阶段实现

直接在CI的脚本阶段调用Prometheus API获取指标值,通过对比结果的退出码控制阶段成败。

具体脚本示例

# 配置Prometheus地址和查询时间范围
PROMETHEUS_URL="http://your-prometheus-instance:9090"
QUERY_RANGE="5m"

# 查询MetricA的sum(rate)结果
METRIC_A=$(curl -s "$PROMETHEUS_URL/api/v1/query?query=sum(rate(MetricA{}[$QUERY_RANGE]))" | jq -r '.data.result[0].value[1]')
# 查询MetricB的sum(rate)结果
METRIC_B=$(curl -s "$PROMETHEUS_URL/api/v1/query?query=sum(rate(MetricB{}[$QUERY_RANGE]))" | jq -r '.data.result[0].value[1]')

# 处理指标查询为空的异常情况
if [[ -z "$METRIC_A" || -z "$METRIC_B" ]]; then
    echo "Failed to fetch metrics from Prometheus"
    exit 1
fi

# 浮点数对比,满足条件则返回非0退出码触发阶段失败
if (( $(echo "$METRIC_A > $METRIC_B" | bc -l) )); then
    echo "Failed: sum(rate(MetricA)) ($METRIC_A) is greater than sum(rate(MetricB)) ($METRIC_B)"
    exit 1
else
    echo "Passed: sum(rate(MetricA)) ($METRIC_A) is less than or equal to sum(rate(MetricB)) ($METRIC_B)"
    exit 0
fi

注意事项

  • 确保CI环境已安装curl、jq(用于解析JSON)和bc(用于浮点数计算)
  • 根据实际业务调整QUERY_RANGE(比如改为1m或10m)
  • 若指标存在标签过滤需求,可修改查询语句(如MetricA{env="prod"})

二、Webhook阶段实现

通过自定义Webhook服务完成指标对比,CI阶段只需调用该服务,根据返回状态码判断成败。

1. 编写Webhook服务示例(Python Flask)

from flask import Flask, jsonify
import requests

app = Flask(__name__)

# 配置Prometheus地址和查询参数
PROMETHEUS_CONFIG = {
    "url": "http://your-prometheus-instance:9090",
    "range": "5m"
}

@app.route('/verify-metrics', methods=['GET'])
def verify_metrics():
    try:
        # 查询两个指标的sum(rate)值
        resp_a = requests.get(
            f"{PROMETHEUS_CONFIG['url']}/api/v1/query",
            params={"query": f"sum(rate(MetricA{{}}[{PROMETHEUS_CONFIG['range']}]))"}
        )
        resp_b = requests.get(
            f"{PROMETHEUS_CONFIG['url']}/api/v1/query",
            params={"query": f"sum(rate(MetricB{{}}[{PROMETHEUS_CONFIG['range']}]))"}
        )
        
        resp_a.raise_for_status()
        resp_b.raise_for_status()
        
        metric_a = float(resp_a.json()['data']['result'][0]['value'][1])
        metric_b = float(resp_b.json()['data']['result'][0]['value'][1])
        
        if metric_a > metric_b:
            return jsonify({"status": "failed", "message": f"MetricA ({metric_a}) exceeds MetricB ({metric_b})"}), 400
        else:
            return jsonify({"status": "passed", "message": f"Metrics check passed"}), 200
            
    except Exception as e:
        return jsonify({"status": "error", "message": str(e)}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

2. CI阶段配置Webhook

在CI的Webhook阶段中设置:

  • 请求URL:http://your-webhook-service:5000/verify-metrics
  • 请求方法:GET
  • 失败触发条件:当Webhook返回非200状态码时,标记该阶段失败

注意事项

  • 确保Webhook服务能被CI环境访问(可部署在同一集群或打通网络)
  • 可添加API密钥等认证机制提升安全性
  • 服务中需处理指标查询失败、无返回结果等异常场景

三、其他可行方案

1. 借助Prometheus Alertmanager

  • 先在Alertmanager中配置告警规则:
    groups:
    - name: metric_comparison
      rules:
      - alert: MetricAExceedsMetricB
        expr: sum(rate(MetricA{}[5m])) > sum(rate(MetricB{}[5m]))
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "MetricA exceeds MetricB"
    
  • 在CI脚本中使用amtool查询告警状态:
    # 查询是否有触发中的目标告警
    amtool alert query alertname="MetricAExceedsMetricB" | grep -q "firing"
    if [ $? -eq 0 ]; then
        echo "Failed: MetricA exceeds MetricB (alert is firing)"
        exit 1
    fi
    

2. CI原生监控集成

部分CI平台(如GitLab CI)支持直接集成Prometheus,可在CI配置中直接定义指标查询和判断逻辑,无需额外脚本或服务。

内容的提问来源于stack exchange,提问作者Aman Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:12:47