Repository navigation
Expand file tree
/
Copy pathdata_sources_prometheus.go
More file actions
70 lines (62 loc) · 2.62 KB
/
Copy pathdata_sources_prometheus.go
File metadata and controls
70 lines (62 loc) · 2.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package flashduty
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
"strings"
)
// ReadPrometheusLabelValues lists the values of one label from a
// Prometheus-compatible data source, through the Monitors proxy.
//
// Unlike the generated typed endpoints, the response body is the data
// source's native Prometheus HTTP API payload: it is not wrapped in the
// Flashduty {request_id, error, data} envelope, so decoding goes straight
// into PrometheusLabelValuesResponse. A non-2xx status can come from either
// side of the proxy — the platform itself (plain text, raised before the
// data source is reached) or the data source (its own JSON error shape,
// distinct from Flashduty's) — so the raw body is carried as-is on the
// returned error's Message rather than parsed as a Flashduty error.
//
// API: GET /monit/prometheus/api/v1/label/{label_name}/values (monit-prometheus-read-label-values).
func (s *DataSourcesService) ReadPrometheusLabelValues(ctx context.Context, dataSourceID uint64, labelName string) (*PrometheusLabelValuesResponse, *Response, error) {
if dataSourceID == 0 {
return nil, nil, fmt.Errorf("flashduty: data source id is required")
}
labelName = strings.TrimSpace(labelName)
if labelName == "" {
return nil, nil, fmt.Errorf("flashduty: label name is required")
}
path := "/monit/prometheus/api/v1/label/" + url.PathEscape(labelName) + "/values"
httpReq, err := s.client.newRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
httpReq.Header.Set("X-DSID", strconv.FormatUint(dataSourceID, 10))
httpResp, err := s.client.client.Do(httpReq)
if err != nil {
return nil, nil, fmt.Errorf("flashduty: request to %s failed: %v", sanitizeURL(httpReq.URL), sanitizeError(err))
}
defer func() { _ = httpResp.Body.Close() }()
resp := &Response{Response: httpResp, RequestID: httpResp.Header.Get("Flashcat-Request-Id")}
resp.RateLimit = parseRateLimit(httpResp.Header)
raw, err := io.ReadAll(io.LimitReader(httpResp.Body, maxResponseBodySize))
if err != nil {
return nil, resp, fmt.Errorf("flashduty: reading response body: %w", err)
}
if httpResp.StatusCode < 200 || httpResp.StatusCode >= 300 {
apiErr := &ErrorResponse{Response: httpResp, Message: strings.TrimSpace(string(raw)), RequestID: resp.RequestID}
return nil, resp, asAPIError(apiErr, resp.RateLimit)
}
out := new(PrometheusLabelValuesResponse)
if len(bytes.TrimSpace(raw)) > 0 {
if err := json.Unmarshal(raw, out); err != nil {
return nil, resp, fmt.Errorf("flashduty: decoding response into %T (request_id %s): %w", out, resp.RequestID, err)
}
}
return out, resp, nil
}