github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/prometheus/common/model/alert.go (about) 1 // Copyright 2013 The Prometheus Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package model 15 16 import ( 17 "fmt" 18 "time" 19 ) 20 21 type AlertStatus string 22 23 const ( 24 AlertFiring AlertStatus = "firing" 25 AlertResolved AlertStatus = "resolved" 26 ) 27 28 // Alert is a generic representation of an alert in the Prometheus eco-system. 29 type Alert struct { 30 // Label value pairs for purpose of aggregation, matching, and disposition 31 // dispatching. This must minimally include an "alertname" label. 32 Labels LabelSet `json:"labels"` 33 34 // Extra key/value information which does not define alert identity. 35 Annotations LabelSet `json:"annotations"` 36 37 // The known time range for this alert. Both ends are optional. 38 StartsAt time.Time `json:"startsAt,omitempty"` 39 EndsAt time.Time `json:"endsAt,omitempty"` 40 GeneratorURL string `json:"generatorURL"` 41 } 42 43 // Name returns the name of the alert. It is equivalent to the "alertname" label. 44 func (a *Alert) Name() string { 45 return string(a.Labels[AlertNameLabel]) 46 } 47 48 // Fingerprint returns a unique hash for the alert. It is equivalent to 49 // the fingerprint of the alert's label set. 50 func (a *Alert) Fingerprint() Fingerprint { 51 return a.Labels.Fingerprint() 52 } 53 54 func (a *Alert) String() string { 55 s := fmt.Sprintf("%s[%s]", a.Name(), a.Fingerprint().String()[:7]) 56 if a.Resolved() { 57 return s + "[resolved]" 58 } 59 return s + "[active]" 60 } 61 62 // Resolved returns true iff the activity interval ended in the past. 63 func (a *Alert) Resolved() bool { 64 return a.ResolvedAt(time.Now()) 65 } 66 67 // ResolvedAt returns true off the activity interval ended before 68 // the given timestamp. 69 func (a *Alert) ResolvedAt(ts time.Time) bool { 70 if a.EndsAt.IsZero() { 71 return false 72 } 73 return !a.EndsAt.After(ts) 74 } 75 76 // Status returns the status of the alert. 77 func (a *Alert) Status() AlertStatus { 78 if a.Resolved() { 79 return AlertResolved 80 } 81 return AlertFiring 82 } 83 84 // Validate checks whether the alert data is inconsistent. 85 func (a *Alert) Validate() error { 86 if a.StartsAt.IsZero() { 87 return fmt.Errorf("start time missing") 88 } 89 if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) { 90 return fmt.Errorf("start time must be before end time") 91 } 92 if err := a.Labels.Validate(); err != nil { 93 return fmt.Errorf("invalid label set: %s", err) 94 } 95 if len(a.Labels) == 0 { 96 return fmt.Errorf("at least one label pair required") 97 } 98 if err := a.Annotations.Validate(); err != nil { 99 return fmt.Errorf("invalid annotations: %s", err) 100 } 101 return nil 102 } 103 104 // Alert is a list of alerts that can be sorted in chronological order. 105 type Alerts []*Alert 106 107 func (as Alerts) Len() int { return len(as) } 108 func (as Alerts) Swap(i, j int) { as[i], as[j] = as[j], as[i] } 109 110 func (as Alerts) Less(i, j int) bool { 111 if as[i].StartsAt.Before(as[j].StartsAt) { 112 return true 113 } 114 if as[i].EndsAt.Before(as[j].EndsAt) { 115 return true 116 } 117 return as[i].Fingerprint() < as[j].Fingerprint() 118 } 119 120 // HasFiring returns true iff one of the alerts is not resolved. 121 func (as Alerts) HasFiring() bool { 122 for _, a := range as { 123 if !a.Resolved() { 124 return true 125 } 126 } 127 return false 128 } 129 130 // Status returns StatusFiring iff at least one of the alerts is firing. 131 func (as Alerts) Status() AlertStatus { 132 if as.HasFiring() { 133 return AlertFiring 134 } 135 return AlertResolved 136 }