| khenaidoo | 59ce9dd | 2019-11-11 13:05:32 -0500 | [diff] [blame] | 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 | "encoding/json" |
| 18 | "fmt" |
| 19 | "regexp" |
| 20 | "strings" |
| 21 | "unicode/utf8" |
| 22 | ) |
| 23 | |
| 24 | const ( |
| Abhay Kumar | 40252eb | 2025-10-13 13:25:53 +0000 | [diff] [blame] | 25 | // AlertNameLabel is the name of the label containing the alert's name. |
| khenaidoo | 59ce9dd | 2019-11-11 13:05:32 -0500 | [diff] [blame] | 26 | AlertNameLabel = "alertname" |
| 27 | |
| 28 | // ExportedLabelPrefix is the prefix to prepend to the label names present in |
| 29 | // exported metrics if a label of the same name is added by the server. |
| 30 | ExportedLabelPrefix = "exported_" |
| 31 | |
| 32 | // MetricNameLabel is the label name indicating the metric name of a |
| 33 | // timeseries. |
| 34 | MetricNameLabel = "__name__" |
| Abhay Kumar | 40252eb | 2025-10-13 13:25:53 +0000 | [diff] [blame] | 35 | // MetricTypeLabel is the label name indicating the metric type of |
| 36 | // timeseries as per the PROM-39 proposal. |
| 37 | MetricTypeLabel = "__type__" |
| 38 | // MetricUnitLabel is the label name indicating the metric unit of |
| 39 | // timeseries as per the PROM-39 proposal. |
| 40 | MetricUnitLabel = "__unit__" |
| khenaidoo | 59ce9dd | 2019-11-11 13:05:32 -0500 | [diff] [blame] | 41 | |
| 42 | // SchemeLabel is the name of the label that holds the scheme on which to |
| 43 | // scrape a target. |
| 44 | SchemeLabel = "__scheme__" |
| 45 | |
| 46 | // AddressLabel is the name of the label that holds the address of |
| 47 | // a scrape target. |
| 48 | AddressLabel = "__address__" |
| 49 | |
| 50 | // MetricsPathLabel is the name of the label that holds the path on which to |
| 51 | // scrape a target. |
| 52 | MetricsPathLabel = "__metrics_path__" |
| 53 | |
| khenaidoo | 2672188 | 2021-08-11 17:42:52 -0400 | [diff] [blame] | 54 | // ScrapeIntervalLabel is the name of the label that holds the scrape interval |
| 55 | // used to scrape a target. |
| 56 | ScrapeIntervalLabel = "__scrape_interval__" |
| 57 | |
| 58 | // ScrapeTimeoutLabel is the name of the label that holds the scrape |
| 59 | // timeout used to scrape a target. |
| 60 | ScrapeTimeoutLabel = "__scrape_timeout__" |
| 61 | |
| khenaidoo | 59ce9dd | 2019-11-11 13:05:32 -0500 | [diff] [blame] | 62 | // ReservedLabelPrefix is a prefix which is not legal in user-supplied |
| 63 | // label names. |
| 64 | ReservedLabelPrefix = "__" |
| 65 | |
| 66 | // MetaLabelPrefix is a prefix for labels that provide meta information. |
| 67 | // Labels with this prefix are used for intermediate label processing and |
| 68 | // will not be attached to time series. |
| 69 | MetaLabelPrefix = "__meta_" |
| 70 | |
| 71 | // TmpLabelPrefix is a prefix for temporary labels as part of relabelling. |
| 72 | // Labels with this prefix are used for intermediate label processing and |
| 73 | // will not be attached to time series. This is reserved for use in |
| 74 | // Prometheus configuration files by users. |
| 75 | TmpLabelPrefix = "__tmp_" |
| 76 | |
| 77 | // ParamLabelPrefix is a prefix for labels that provide URL parameters |
| 78 | // used to scrape a target. |
| 79 | ParamLabelPrefix = "__param_" |
| 80 | |
| 81 | // JobLabel is the label name indicating the job from which a timeseries |
| 82 | // was scraped. |
| 83 | JobLabel = "job" |
| 84 | |
| 85 | // InstanceLabel is the label name used for the instance label. |
| 86 | InstanceLabel = "instance" |
| 87 | |
| 88 | // BucketLabel is used for the label that defines the upper bound of a |
| 89 | // bucket of a histogram ("le" -> "less or equal"). |
| 90 | BucketLabel = "le" |
| 91 | |
| 92 | // QuantileLabel is used for the label that defines the quantile in a |
| 93 | // summary. |
| 94 | QuantileLabel = "quantile" |
| 95 | ) |
| 96 | |
| 97 | // LabelNameRE is a regular expression matching valid label names. Note that the |
| 98 | // IsValid method of LabelName performs the same check but faster than a match |
| 99 | // with this regular expression. |
| 100 | var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") |
| 101 | |
| 102 | // A LabelName is a key for a LabelSet or Metric. It has a value associated |
| 103 | // therewith. |
| 104 | type LabelName string |
| 105 | |
| Abhay Kumar | 40252eb | 2025-10-13 13:25:53 +0000 | [diff] [blame] | 106 | // IsValid returns true iff the name matches the pattern of LabelNameRE when |
| 107 | // NameValidationScheme is set to LegacyValidation, or valid UTF-8 if |
| 108 | // NameValidationScheme is set to UTF8Validation. |
| 109 | // |
| 110 | // Deprecated: This method should not be used and may be removed in the future. |
| 111 | // Use [ValidationScheme.IsValidLabelName] instead. |
| khenaidoo | 59ce9dd | 2019-11-11 13:05:32 -0500 | [diff] [blame] | 112 | func (ln LabelName) IsValid() bool { |
| Abhay Kumar | 40252eb | 2025-10-13 13:25:53 +0000 | [diff] [blame] | 113 | return NameValidationScheme.IsValidLabelName(string(ln)) |
| 114 | } |
| 115 | |
| 116 | // IsValidLegacy returns true iff name matches the pattern of LabelNameRE for |
| 117 | // legacy names. It does not use LabelNameRE for the check but a much faster |
| 118 | // hardcoded implementation. |
| 119 | // |
| 120 | // Deprecated: This method should not be used and may be removed in the future. |
| 121 | // Use [LegacyValidation.IsValidLabelName] instead. |
| 122 | func (ln LabelName) IsValidLegacy() bool { |
| 123 | return LegacyValidation.IsValidLabelName(string(ln)) |
| khenaidoo | 59ce9dd | 2019-11-11 13:05:32 -0500 | [diff] [blame] | 124 | } |
| 125 | |
| 126 | // UnmarshalYAML implements the yaml.Unmarshaler interface. |
| 127 | func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { |
| 128 | var s string |
| 129 | if err := unmarshal(&s); err != nil { |
| 130 | return err |
| 131 | } |
| 132 | if !LabelName(s).IsValid() { |
| 133 | return fmt.Errorf("%q is not a valid label name", s) |
| 134 | } |
| 135 | *ln = LabelName(s) |
| 136 | return nil |
| 137 | } |
| 138 | |
| 139 | // UnmarshalJSON implements the json.Unmarshaler interface. |
| 140 | func (ln *LabelName) UnmarshalJSON(b []byte) error { |
| 141 | var s string |
| 142 | if err := json.Unmarshal(b, &s); err != nil { |
| 143 | return err |
| 144 | } |
| 145 | if !LabelName(s).IsValid() { |
| 146 | return fmt.Errorf("%q is not a valid label name", s) |
| 147 | } |
| 148 | *ln = LabelName(s) |
| 149 | return nil |
| 150 | } |
| 151 | |
| 152 | // LabelNames is a sortable LabelName slice. In implements sort.Interface. |
| 153 | type LabelNames []LabelName |
| 154 | |
| 155 | func (l LabelNames) Len() int { |
| 156 | return len(l) |
| 157 | } |
| 158 | |
| 159 | func (l LabelNames) Less(i, j int) bool { |
| 160 | return l[i] < l[j] |
| 161 | } |
| 162 | |
| 163 | func (l LabelNames) Swap(i, j int) { |
| 164 | l[i], l[j] = l[j], l[i] |
| 165 | } |
| 166 | |
| 167 | func (l LabelNames) String() string { |
| 168 | labelStrings := make([]string, 0, len(l)) |
| 169 | for _, label := range l { |
| 170 | labelStrings = append(labelStrings, string(label)) |
| 171 | } |
| 172 | return strings.Join(labelStrings, ", ") |
| 173 | } |
| 174 | |
| 175 | // A LabelValue is an associated value for a LabelName. |
| 176 | type LabelValue string |
| 177 | |
| Abhay Kumar | 40252eb | 2025-10-13 13:25:53 +0000 | [diff] [blame] | 178 | // IsValid returns true iff the string is a valid UTF-8. |
| khenaidoo | 59ce9dd | 2019-11-11 13:05:32 -0500 | [diff] [blame] | 179 | func (lv LabelValue) IsValid() bool { |
| 180 | return utf8.ValidString(string(lv)) |
| 181 | } |
| 182 | |
| 183 | // LabelValues is a sortable LabelValue slice. It implements sort.Interface. |
| 184 | type LabelValues []LabelValue |
| 185 | |
| 186 | func (l LabelValues) Len() int { |
| 187 | return len(l) |
| 188 | } |
| 189 | |
| 190 | func (l LabelValues) Less(i, j int) bool { |
| 191 | return string(l[i]) < string(l[j]) |
| 192 | } |
| 193 | |
| 194 | func (l LabelValues) Swap(i, j int) { |
| 195 | l[i], l[j] = l[j], l[i] |
| 196 | } |
| 197 | |
| 198 | // LabelPair pairs a name with a value. |
| 199 | type LabelPair struct { |
| 200 | Name LabelName |
| 201 | Value LabelValue |
| 202 | } |
| 203 | |
| 204 | // LabelPairs is a sortable slice of LabelPair pointers. It implements |
| 205 | // sort.Interface. |
| 206 | type LabelPairs []*LabelPair |
| 207 | |
| 208 | func (l LabelPairs) Len() int { |
| 209 | return len(l) |
| 210 | } |
| 211 | |
| 212 | func (l LabelPairs) Less(i, j int) bool { |
| 213 | switch { |
| 214 | case l[i].Name > l[j].Name: |
| 215 | return false |
| 216 | case l[i].Name < l[j].Name: |
| 217 | return true |
| 218 | case l[i].Value > l[j].Value: |
| 219 | return false |
| 220 | case l[i].Value < l[j].Value: |
| 221 | return true |
| 222 | default: |
| 223 | return false |
| 224 | } |
| 225 | } |
| 226 | |
| 227 | func (l LabelPairs) Swap(i, j int) { |
| 228 | l[i], l[j] = l[j], l[i] |
| 229 | } |