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
14package model
15
16import (
17	"encoding/json"
18	"fmt"
19	"regexp"
20	"sort"
21	"strings"
22)
23
24const (
25	// AlertNameLabel is the name of the label containing the an alert's name.
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__"
35
36	// SchemeLabel is the name of the label that holds the scheme on which to
37	// scrape a target.
38	SchemeLabel = "__scheme__"
39
40	// AddressLabel is the name of the label that holds the address of
41	// a scrape target.
42	AddressLabel = "__address__"
43
44	// MetricsPathLabel is the name of the label that holds the path on which to
45	// scrape a target.
46	MetricsPathLabel = "__metrics_path__"
47
48	// ReservedLabelPrefix is a prefix which is not legal in user-supplied
49	// label names.
50	ReservedLabelPrefix = "__"
51
52	// MetaLabelPrefix is a prefix for labels that provide meta information.
53	// Labels with this prefix are used for intermediate label processing and
54	// will not be attached to time series.
55	MetaLabelPrefix = "__meta_"
56
57	// TmpLabelPrefix is a prefix for temporary labels as part of relabelling.
58	// Labels with this prefix are used for intermediate label processing and
59	// will not be attached to time series. This is reserved for use in
60	// Prometheus configuration files by users.
61	TmpLabelPrefix = "__tmp_"
62
63	// ParamLabelPrefix is a prefix for labels that provide URL parameters
64	// used to scrape a target.
65	ParamLabelPrefix = "__param_"
66
67	// JobLabel is the label name indicating the job from which a timeseries
68	// was scraped.
69	JobLabel = "job"
70
71	// InstanceLabel is the label name used for the instance label.
72	InstanceLabel = "instance"
73
74	// BucketLabel is used for the label that defines the upper bound of a
75	// bucket of a histogram ("le" -> "less or equal").
76	BucketLabel = "le"
77
78	// QuantileLabel is used for the label that defines the quantile in a
79	// summary.
80	QuantileLabel = "quantile"
81)
82
83// LabelNameRE is a regular expression matching valid label names.
84var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
85
86// A LabelName is a key for a LabelSet or Metric.  It has a value associated
87// therewith.
88type LabelName string
89
90// UnmarshalYAML implements the yaml.Unmarshaler interface.
91func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error {
92	var s string
93	if err := unmarshal(&s); err != nil {
94		return err
95	}
96	if !LabelNameRE.MatchString(s) {
97		return fmt.Errorf("%q is not a valid label name", s)
98	}
99	*ln = LabelName(s)
100	return nil
101}
102
103// UnmarshalJSON implements the json.Unmarshaler interface.
104func (ln *LabelName) UnmarshalJSON(b []byte) error {
105	var s string
106	if err := json.Unmarshal(b, &s); err != nil {
107		return err
108	}
109	if !LabelNameRE.MatchString(s) {
110		return fmt.Errorf("%q is not a valid label name", s)
111	}
112	*ln = LabelName(s)
113	return nil
114}
115
116// LabelNames is a sortable LabelName slice. In implements sort.Interface.
117type LabelNames []LabelName
118
119func (l LabelNames) Len() int {
120	return len(l)
121}
122
123func (l LabelNames) Less(i, j int) bool {
124	return l[i] < l[j]
125}
126
127func (l LabelNames) Swap(i, j int) {
128	l[i], l[j] = l[j], l[i]
129}
130
131func (l LabelNames) String() string {
132	labelStrings := make([]string, 0, len(l))
133	for _, label := range l {
134		labelStrings = append(labelStrings, string(label))
135	}
136	return strings.Join(labelStrings, ", ")
137}
138
139// A LabelValue is an associated value for a LabelName.
140type LabelValue string
141
142// LabelValues is a sortable LabelValue slice. It implements sort.Interface.
143type LabelValues []LabelValue
144
145func (l LabelValues) Len() int {
146	return len(l)
147}
148
149func (l LabelValues) Less(i, j int) bool {
150	return sort.StringsAreSorted([]string{string(l[i]), string(l[j])})
151}
152
153func (l LabelValues) Swap(i, j int) {
154	l[i], l[j] = l[j], l[i]
155}
156
157// LabelPair pairs a name with a value.
158type LabelPair struct {
159	Name  LabelName
160	Value LabelValue
161}
162
163// LabelPairs is a sortable slice of LabelPair pointers. It implements
164// sort.Interface.
165type LabelPairs []*LabelPair
166
167func (l LabelPairs) Len() int {
168	return len(l)
169}
170
171func (l LabelPairs) Less(i, j int) bool {
172	switch {
173	case l[i].Name > l[j].Name:
174		return false
175	case l[i].Name < l[j].Name:
176		return true
177	case l[i].Value > l[j].Value:
178		return false
179	case l[i].Value < l[j].Value:
180		return true
181	default:
182		return false
183	}
184}
185
186func (l LabelPairs) Swap(i, j int) {
187	l[i], l[j] = l[j], l[i]
188}
189