cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.28.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/promapi/config.go

105lines · modecode

1package promapi
2
3import (
4 "context"
5 "crypto/sha1"
6 "fmt"
7 "io"
8 "time"
9
10 v1 "github.com/prometheus/client_golang/api/prometheus/v1"
11 "github.com/rs/zerolog/log"
12 "gopkg.in/yaml.v3"
13)
14
15type ConfigSectionGlobal struct {
16 ScrapeInterval time.Duration `yaml:"scrape_interval"`
17 ScrapeTimeout time.Duration `yaml:"scrape_timeout"`
18 EvaluationInterval time.Duration `yaml:"evaluation_interval"`
19 ExternalLabels map[string]string `yaml:"external_labels"`
20}
21
22type PrometheusConfig struct {
23 Global ConfigSectionGlobal `yaml:"global"`
24}
25
26type ConfigResult struct {
27 URI string
28 Config PrometheusConfig
29}
30
31type configQuery struct {
32 prom *Prometheus
33 ctx context.Context
34 timestamp time.Time
35}
36
37func (q configQuery) Run() (any, error) {
38 log.Debug().
39 Str("uri", q.prom.uri).
40 Msg("Getting prometheus configuration")
41
42 ctx, cancel := context.WithTimeout(q.ctx, q.prom.timeout)
43 defer cancel()
44
45 v, err := q.prom.api.Config(ctx)
46 if err != nil {
47 return nil, fmt.Errorf("failed to query Prometheus config: %w", err)
48 }
49 return v, nil
50}
51
52func (q configQuery) Endpoint() string {
53 return "/api/v1/status/config"
54}
55
56func (q configQuery) String() string {
57 return "/api/v1/status/config"
58}
59
60func (q configQuery) CacheKey() string {
61 h := sha1.New()
62 _, _ = io.WriteString(h, q.Endpoint())
63 _, _ = io.WriteString(h, "\n")
64 _, _ = io.WriteString(h, q.timestamp.Round(cacheExpiry).Format(time.RFC3339))
65 return fmt.Sprintf("%x", h.Sum(nil))
66}
67
68func (p *Prometheus) Config(ctx context.Context) (*ConfigResult, error) {
69 log.Debug().Str("uri", p.uri).Msg("Scheduling Prometheus configuration query")
70
71 key := "/api/v1/status/config"
72 p.locker.lock(key)
73 defer p.locker.unlock(key)
74
75 resultChan := make(chan queryResult)
76 p.queries <- queryRequest{
77 query: configQuery{prom: p, ctx: ctx, timestamp: time.Now()},
78 result: resultChan,
79 }
80
81 result := <-resultChan
82 if result.err != nil {
83 return nil, QueryError{err: result.err, msg: decodeError(result.err)}
84 }
85
86 var cfg PrometheusConfig
87 if err := yaml.Unmarshal([]byte(result.value.(v1.ConfigResult).YAML), &cfg); err != nil {
88 prometheusQueryErrorsTotal.WithLabelValues(p.name, "/api/v1/status/config", errReason(err)).Inc()
89 return nil, fmt.Errorf("failed to decode config data in %s response: %w", p.uri, err)
90 }
91
92 if cfg.Global.ScrapeInterval == 0 {
93 cfg.Global.ScrapeInterval = time.Minute
94 }
95 if cfg.Global.ScrapeTimeout == 0 {
96 cfg.Global.ScrapeTimeout = time.Second * 10
97 }
98 if cfg.Global.EvaluationInterval == 0 {
99 cfg.Global.EvaluationInterval = time.Minute
100 }
101
102 r := ConfigResult{URI: p.uri, Config: cfg}
103
104 return &r, nil
105}
106