cloudflare/pint

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.4.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

internal/checks/alerts_count.go

111lines · modecode

1package checks
2
3import (
4 "fmt"
5 "sort"
6 "time"
7
8 "github.com/cloudflare/pint/internal/parser"
9 "github.com/cloudflare/pint/internal/promapi"
10)
11
12const (
13 AlertsCheckName = "alerts/count"
14)
15
16func NewAlertsCheck(name, uri string, timeout, lookBack, step, resolve time.Duration) AlertsCheck {
17 return AlertsCheck{
18 name: name,
19 uri: uri,
20 timeout: timeout,
21 lookBack: lookBack,
22 step: step,
23 resolve: resolve,
24 }
25}
26
27type AlertsCheck struct {
28 name string
29 uri string
30 timeout time.Duration
31 lookBack time.Duration
32 step time.Duration
33 resolve time.Duration
34}
35
36func (c AlertsCheck) String() string {
37 return fmt.Sprintf("%s(%s)", AlertsCheckName, c.name)
38}
39
40func (c AlertsCheck) Check(rule parser.Rule) (problems []Problem) {
41 if rule.AlertingRule == nil {
42 return
43 }
44
45 if rule.AlertingRule.Expr.SyntaxError != nil {
46 return
47 }
48
49 end := time.Now()
50 start := end.Add(-1 * c.lookBack)
51
52 qr, err := promapi.RangeQuery(c.uri, c.timeout, rule.AlertingRule.Expr.Value.Value, start, end, c.step, nil)
53 if err != nil {
54 problems = append(problems, Problem{
55 Fragment: rule.AlertingRule.Expr.Value.Value,
56 Lines: rule.AlertingRule.Expr.Lines(),
57 Reporter: AlertsCheckName,
58 Text: fmt.Sprintf("query using %s failed with: %s", c.name, err),
59 Severity: Bug,
60 })
61 return
62 }
63
64 var forDur time.Duration
65 if rule.AlertingRule.For != nil {
66 forDur, _ = time.ParseDuration(rule.AlertingRule.For.Value.Value)
67 }
68
69 var alerts int
70 for _, sample := range qr.Samples {
71 var isAlerting, isNew bool
72 var firstTime, lastTime time.Time
73 for _, value := range sample.Values {
74 isNew = value.Timestamp.Time().After(lastTime.Add(c.step))
75 if isNew {
76 if rule.AlertingRule.For != nil {
77 isAlerting = false
78 } else {
79 isAlerting = true
80 alerts++
81 }
82 firstTime = value.Timestamp.Time()
83 } else {
84 if !isAlerting && rule.AlertingRule.For != nil {
85 if !value.Timestamp.Time().Before(firstTime.Add(forDur)) {
86 isAlerting = true
87 alerts++
88 }
89 }
90 }
91 lastTime = value.Timestamp.Time()
92 }
93 }
94
95 lines := []int{}
96 lines = append(lines, rule.AlertingRule.Expr.Lines()...)
97 if rule.AlertingRule.For != nil {
98 lines = append(lines, rule.AlertingRule.For.Lines()...)
99 }
100 sort.Ints(lines)
101
102 delta := qr.End.Sub(qr.Start)
103 problems = append(problems, Problem{
104 Fragment: rule.AlertingRule.Expr.Value.Value,
105 Lines: lines,
106 Reporter: AlertsCheckName,
107 Text: fmt.Sprintf("query using %s would trigger %d alert(s) in the last %s", c.name, alerts, promapi.HumanizeDuration(delta)),
108 Severity: Information,
109 })
110 return
111}
112