mirror of
https://github.com/fluxcd/flagger.git
synced 2026-03-02 17:51:00 +00:00
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package controller
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
)
|
|
|
|
type VectorQueryResponse struct {
|
|
Data struct {
|
|
Result []struct {
|
|
Metric struct {
|
|
Code string `json:"response_code"`
|
|
Name string `json:"destination_workload"`
|
|
}
|
|
Value []interface{} `json:"value"`
|
|
}
|
|
}
|
|
}
|
|
|
|
func (c *Controller) queryMetric(query string) (*VectorQueryResponse, error) {
|
|
promURL, err := url.Parse(c.metricServer)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
u, err := url.Parse(fmt.Sprintf("./api/v1/query?query=%s", query))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
u = promURL.ResolveReference(u)
|
|
r, err := http.Get(u.String())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer r.Body.Close()
|
|
b, err := ioutil.ReadAll(r.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error reading body: %s", err.Error())
|
|
}
|
|
|
|
if 400 <= r.StatusCode {
|
|
return nil, fmt.Errorf("error response: %s", string(b))
|
|
}
|
|
var values VectorQueryResponse
|
|
|
|
err = json.Unmarshal(b, &values)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error unmarshaling result: %s, '%s'", err.Error(), string(b))
|
|
}
|
|
|
|
return &values, nil
|
|
|
|
}
|
|
|
|
func (c *Controller) getDeploymentMetric(name string, namespace string, counter string, interval string) (float64, error) {
|
|
var rate float64
|
|
querySt := url.QueryEscape(`sum(rate(` +
|
|
counter + `{reporter="destination",destination_workload_namespace=~"` +
|
|
namespace + `",destination_workload=~"` +
|
|
name + `",response_code!~"5.*"}[1m])) / sum(rate(` +
|
|
counter + `{reporter="destination",destination_workload_namespace=~"` +
|
|
namespace + `",destination_workload=~"` +
|
|
name + `"}[` +
|
|
interval + `])) * 100 `)
|
|
result, err := c.queryMetric(querySt)
|
|
if err != nil {
|
|
return rate, err
|
|
}
|
|
|
|
for _, v := range result.Data.Result {
|
|
metricValue := v.Value[1]
|
|
switch metricValue.(type) {
|
|
case string:
|
|
f, err := strconv.ParseFloat(metricValue.(string), 64)
|
|
if err != nil {
|
|
return rate, err
|
|
}
|
|
rate = f
|
|
}
|
|
}
|
|
return rate, nil
|
|
}
|