cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.25.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/promapi/query.go

90lines · modecode

1package promapi
2
3import (
4 "context"
5 "crypto/sha1"
6 "fmt"
7 "io"
8 "time"
9
10 "github.com/prometheus/common/model"
11 "github.com/rs/zerolog/log"
12)
13
14type QueryResult struct {
15 URI string
16 Series model.Vector
17}
18
19type instantQuery struct {
20 prom *Prometheus
21 ctx context.Context
22 expr string
23 timestamp time.Time
24}
25
26func (q instantQuery) Run() (any, error) {
27 log.Debug().
28 Str("uri", q.prom.uri).
29 Str("query", q.expr).
30 Msg("Running prometheus query")
31
32 ctx, cancel := context.WithTimeout(q.ctx, q.prom.timeout)
33 defer cancel()
34
35 v, _, err := q.prom.api.Query(ctx, q.expr, time.Now())
36 return v, err
37}
38
39func (q instantQuery) Endpoint() string {
40 return "/api/v1/query"
41}
42
43func (q instantQuery) String() string {
44 return q.expr
45}
46
47func (q instantQuery) CacheKey() string {
48 h := sha1.New()
49 _, _ = io.WriteString(h, q.Endpoint())
50 _, _ = io.WriteString(h, "\n")
51 _, _ = io.WriteString(h, q.expr)
52 _, _ = io.WriteString(h, "\n")
53 _, _ = io.WriteString(h, q.timestamp.Round(cacheExpiry).Format(time.RFC3339))
54 return fmt.Sprintf("%x", h.Sum(nil))
55}
56
57func (p *Prometheus) Query(ctx context.Context, expr string) (*QueryResult, error) {
58 log.Debug().Str("uri", p.uri).Str("query", expr).Msg("Scheduling prometheus query")
59
60 key := fmt.Sprintf("/api/v1/query/%s", expr)
61 p.locker.lock(key)
62 defer p.locker.unlock(key)
63
64 resultChan := make(chan queryResult)
65 p.queries <- queryRequest{
66 query: instantQuery{prom: p, ctx: ctx, expr: expr, timestamp: time.Now()},
67 result: resultChan,
68 }
69
70 result := <-resultChan
71 if result.err != nil {
72 return nil, QueryError{err: result.err, msg: decodeError(result.err)}
73 }
74
75 qr := QueryResult{URI: p.uri}
76
77 // nolint: exhaustive
78 switch result.value.(model.Value).Type() {
79 case model.ValVector:
80 vectorVal := result.value.(model.Vector)
81 qr.Series = vectorVal
82 default:
83 log.Error().Str("uri", p.uri).Str("query", expr).Msgf("Query returned unknown result type: %v", result.value.(model.Value).Type())
84 prometheusQueryErrorsTotal.WithLabelValues(p.name, "/api/v1/query", "unknown result type").Inc()
85 return nil, fmt.Errorf("unknown result type: %v", result.value.(model.Value).Type())
86 }
87 log.Debug().Str("uri", p.uri).Str("query", expr).Int("series", len(qr.Series)).Msg("Parsed response")
88
89 return &qr, nil
90}
91