go mod vendor
+ move k8s.io/apimachinery fork from go.work to go.mod (and include it in vendor)
This commit is contained in:
		
							
								
								
									
										136
									
								
								vendor/github.com/prometheus/common/model/alert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								vendor/github.com/prometheus/common/model/alert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| type AlertStatus string | ||||
|  | ||||
| const ( | ||||
| 	AlertFiring   AlertStatus = "firing" | ||||
| 	AlertResolved AlertStatus = "resolved" | ||||
| ) | ||||
|  | ||||
| // Alert is a generic representation of an alert in the Prometheus eco-system. | ||||
| type Alert struct { | ||||
| 	// Label value pairs for purpose of aggregation, matching, and disposition | ||||
| 	// dispatching. This must minimally include an "alertname" label. | ||||
| 	Labels LabelSet `json:"labels"` | ||||
|  | ||||
| 	// Extra key/value information which does not define alert identity. | ||||
| 	Annotations LabelSet `json:"annotations"` | ||||
|  | ||||
| 	// The known time range for this alert. Both ends are optional. | ||||
| 	StartsAt     time.Time `json:"startsAt,omitempty"` | ||||
| 	EndsAt       time.Time `json:"endsAt,omitempty"` | ||||
| 	GeneratorURL string    `json:"generatorURL"` | ||||
| } | ||||
|  | ||||
| // Name returns the name of the alert. It is equivalent to the "alertname" label. | ||||
| func (a *Alert) Name() string { | ||||
| 	return string(a.Labels[AlertNameLabel]) | ||||
| } | ||||
|  | ||||
| // Fingerprint returns a unique hash for the alert. It is equivalent to | ||||
| // the fingerprint of the alert's label set. | ||||
| func (a *Alert) Fingerprint() Fingerprint { | ||||
| 	return a.Labels.Fingerprint() | ||||
| } | ||||
|  | ||||
| func (a *Alert) String() string { | ||||
| 	s := fmt.Sprintf("%s[%s]", a.Name(), a.Fingerprint().String()[:7]) | ||||
| 	if a.Resolved() { | ||||
| 		return s + "[resolved]" | ||||
| 	} | ||||
| 	return s + "[active]" | ||||
| } | ||||
|  | ||||
| // Resolved returns true iff the activity interval ended in the past. | ||||
| func (a *Alert) Resolved() bool { | ||||
| 	return a.ResolvedAt(time.Now()) | ||||
| } | ||||
|  | ||||
| // ResolvedAt returns true off the activity interval ended before | ||||
| // the given timestamp. | ||||
| func (a *Alert) ResolvedAt(ts time.Time) bool { | ||||
| 	if a.EndsAt.IsZero() { | ||||
| 		return false | ||||
| 	} | ||||
| 	return !a.EndsAt.After(ts) | ||||
| } | ||||
|  | ||||
| // Status returns the status of the alert. | ||||
| func (a *Alert) Status() AlertStatus { | ||||
| 	if a.Resolved() { | ||||
| 		return AlertResolved | ||||
| 	} | ||||
| 	return AlertFiring | ||||
| } | ||||
|  | ||||
| // Validate checks whether the alert data is inconsistent. | ||||
| func (a *Alert) Validate() error { | ||||
| 	if a.StartsAt.IsZero() { | ||||
| 		return fmt.Errorf("start time missing") | ||||
| 	} | ||||
| 	if !a.EndsAt.IsZero() && a.EndsAt.Before(a.StartsAt) { | ||||
| 		return fmt.Errorf("start time must be before end time") | ||||
| 	} | ||||
| 	if err := a.Labels.Validate(); err != nil { | ||||
| 		return fmt.Errorf("invalid label set: %s", err) | ||||
| 	} | ||||
| 	if len(a.Labels) == 0 { | ||||
| 		return fmt.Errorf("at least one label pair required") | ||||
| 	} | ||||
| 	if err := a.Annotations.Validate(); err != nil { | ||||
| 		return fmt.Errorf("invalid annotations: %s", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Alert is a list of alerts that can be sorted in chronological order. | ||||
| type Alerts []*Alert | ||||
|  | ||||
| func (as Alerts) Len() int      { return len(as) } | ||||
| func (as Alerts) Swap(i, j int) { as[i], as[j] = as[j], as[i] } | ||||
|  | ||||
| func (as Alerts) Less(i, j int) bool { | ||||
| 	if as[i].StartsAt.Before(as[j].StartsAt) { | ||||
| 		return true | ||||
| 	} | ||||
| 	if as[i].EndsAt.Before(as[j].EndsAt) { | ||||
| 		return true | ||||
| 	} | ||||
| 	return as[i].Fingerprint() < as[j].Fingerprint() | ||||
| } | ||||
|  | ||||
| // HasFiring returns true iff one of the alerts is not resolved. | ||||
| func (as Alerts) HasFiring() bool { | ||||
| 	for _, a := range as { | ||||
| 		if !a.Resolved() { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Status returns StatusFiring iff at least one of the alerts is firing. | ||||
| func (as Alerts) Status() AlertStatus { | ||||
| 	if as.HasFiring() { | ||||
| 		return AlertFiring | ||||
| 	} | ||||
| 	return AlertResolved | ||||
| } | ||||
							
								
								
									
										105
									
								
								vendor/github.com/prometheus/common/model/fingerprinting.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/prometheus/common/model/fingerprinting.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| ) | ||||
|  | ||||
| // Fingerprint provides a hash-capable representation of a Metric. | ||||
| // For our purposes, FNV-1A 64-bit is used. | ||||
| type Fingerprint uint64 | ||||
|  | ||||
| // FingerprintFromString transforms a string representation into a Fingerprint. | ||||
| func FingerprintFromString(s string) (Fingerprint, error) { | ||||
| 	num, err := strconv.ParseUint(s, 16, 64) | ||||
| 	return Fingerprint(num), err | ||||
| } | ||||
|  | ||||
| // ParseFingerprint parses the input string into a fingerprint. | ||||
| func ParseFingerprint(s string) (Fingerprint, error) { | ||||
| 	num, err := strconv.ParseUint(s, 16, 64) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return Fingerprint(num), nil | ||||
| } | ||||
|  | ||||
| func (f Fingerprint) String() string { | ||||
| 	return fmt.Sprintf("%016x", uint64(f)) | ||||
| } | ||||
|  | ||||
| // Fingerprints represents a collection of Fingerprint subject to a given | ||||
| // natural sorting scheme. It implements sort.Interface. | ||||
| type Fingerprints []Fingerprint | ||||
|  | ||||
| // Len implements sort.Interface. | ||||
| func (f Fingerprints) Len() int { | ||||
| 	return len(f) | ||||
| } | ||||
|  | ||||
| // Less implements sort.Interface. | ||||
| func (f Fingerprints) Less(i, j int) bool { | ||||
| 	return f[i] < f[j] | ||||
| } | ||||
|  | ||||
| // Swap implements sort.Interface. | ||||
| func (f Fingerprints) Swap(i, j int) { | ||||
| 	f[i], f[j] = f[j], f[i] | ||||
| } | ||||
|  | ||||
| // FingerprintSet is a set of Fingerprints. | ||||
| type FingerprintSet map[Fingerprint]struct{} | ||||
|  | ||||
| // Equal returns true if both sets contain the same elements (and not more). | ||||
| func (s FingerprintSet) Equal(o FingerprintSet) bool { | ||||
| 	if len(s) != len(o) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	for k := range s { | ||||
| 		if _, ok := o[k]; !ok { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // Intersection returns the elements contained in both sets. | ||||
| func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet { | ||||
| 	myLength, otherLength := len(s), len(o) | ||||
| 	if myLength == 0 || otherLength == 0 { | ||||
| 		return FingerprintSet{} | ||||
| 	} | ||||
|  | ||||
| 	subSet := s | ||||
| 	superSet := o | ||||
|  | ||||
| 	if otherLength < myLength { | ||||
| 		subSet = o | ||||
| 		superSet = s | ||||
| 	} | ||||
|  | ||||
| 	out := FingerprintSet{} | ||||
|  | ||||
| 	for k := range subSet { | ||||
| 		if _, ok := superSet[k]; ok { | ||||
| 			out[k] = struct{}{} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return out | ||||
| } | ||||
							
								
								
									
										42
									
								
								vendor/github.com/prometheus/common/model/fnv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/github.com/prometheus/common/model/fnv.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // Copyright 2015 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| // Inline and byte-free variant of hash/fnv's fnv64a. | ||||
|  | ||||
| const ( | ||||
| 	offset64 = 14695981039346656037 | ||||
| 	prime64  = 1099511628211 | ||||
| ) | ||||
|  | ||||
| // hashNew initializes a new fnv64a hash value. | ||||
| func hashNew() uint64 { | ||||
| 	return offset64 | ||||
| } | ||||
|  | ||||
| // hashAdd adds a string to a fnv64a hash value, returning the updated hash. | ||||
| func hashAdd(h uint64, s string) uint64 { | ||||
| 	for i := 0; i < len(s); i++ { | ||||
| 		h ^= uint64(s[i]) | ||||
| 		h *= prime64 | ||||
| 	} | ||||
| 	return h | ||||
| } | ||||
|  | ||||
| // hashAddByte adds a byte to a fnv64a hash value, returning the updated hash. | ||||
| func hashAddByte(h uint64, b byte) uint64 { | ||||
| 	h ^= uint64(b) | ||||
| 	h *= prime64 | ||||
| 	return h | ||||
| } | ||||
							
								
								
									
										218
									
								
								vendor/github.com/prometheus/common/model/labels.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								vendor/github.com/prometheus/common/model/labels.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,218 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"strings" | ||||
| 	"unicode/utf8" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// AlertNameLabel is the name of the label containing the an alert's name. | ||||
| 	AlertNameLabel = "alertname" | ||||
|  | ||||
| 	// ExportedLabelPrefix is the prefix to prepend to the label names present in | ||||
| 	// exported metrics if a label of the same name is added by the server. | ||||
| 	ExportedLabelPrefix = "exported_" | ||||
|  | ||||
| 	// MetricNameLabel is the label name indicating the metric name of a | ||||
| 	// timeseries. | ||||
| 	MetricNameLabel = "__name__" | ||||
|  | ||||
| 	// SchemeLabel is the name of the label that holds the scheme on which to | ||||
| 	// scrape a target. | ||||
| 	SchemeLabel = "__scheme__" | ||||
|  | ||||
| 	// AddressLabel is the name of the label that holds the address of | ||||
| 	// a scrape target. | ||||
| 	AddressLabel = "__address__" | ||||
|  | ||||
| 	// MetricsPathLabel is the name of the label that holds the path on which to | ||||
| 	// scrape a target. | ||||
| 	MetricsPathLabel = "__metrics_path__" | ||||
|  | ||||
| 	// ScrapeIntervalLabel is the name of the label that holds the scrape interval | ||||
| 	// used to scrape a target. | ||||
| 	ScrapeIntervalLabel = "__scrape_interval__" | ||||
|  | ||||
| 	// ScrapeTimeoutLabel is the name of the label that holds the scrape | ||||
| 	// timeout used to scrape a target. | ||||
| 	ScrapeTimeoutLabel = "__scrape_timeout__" | ||||
|  | ||||
| 	// ReservedLabelPrefix is a prefix which is not legal in user-supplied | ||||
| 	// label names. | ||||
| 	ReservedLabelPrefix = "__" | ||||
|  | ||||
| 	// MetaLabelPrefix is a prefix for labels that provide meta information. | ||||
| 	// Labels with this prefix are used for intermediate label processing and | ||||
| 	// will not be attached to time series. | ||||
| 	MetaLabelPrefix = "__meta_" | ||||
|  | ||||
| 	// TmpLabelPrefix is a prefix for temporary labels as part of relabelling. | ||||
| 	// Labels with this prefix are used for intermediate label processing and | ||||
| 	// will not be attached to time series. This is reserved for use in | ||||
| 	// Prometheus configuration files by users. | ||||
| 	TmpLabelPrefix = "__tmp_" | ||||
|  | ||||
| 	// ParamLabelPrefix is a prefix for labels that provide URL parameters | ||||
| 	// used to scrape a target. | ||||
| 	ParamLabelPrefix = "__param_" | ||||
|  | ||||
| 	// JobLabel is the label name indicating the job from which a timeseries | ||||
| 	// was scraped. | ||||
| 	JobLabel = "job" | ||||
|  | ||||
| 	// InstanceLabel is the label name used for the instance label. | ||||
| 	InstanceLabel = "instance" | ||||
|  | ||||
| 	// BucketLabel is used for the label that defines the upper bound of a | ||||
| 	// bucket of a histogram ("le" -> "less or equal"). | ||||
| 	BucketLabel = "le" | ||||
|  | ||||
| 	// QuantileLabel is used for the label that defines the quantile in a | ||||
| 	// summary. | ||||
| 	QuantileLabel = "quantile" | ||||
| ) | ||||
|  | ||||
| // LabelNameRE is a regular expression matching valid label names. Note that the | ||||
| // IsValid method of LabelName performs the same check but faster than a match | ||||
| // with this regular expression. | ||||
| var LabelNameRE = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$") | ||||
|  | ||||
| // A LabelName is a key for a LabelSet or Metric.  It has a value associated | ||||
| // therewith. | ||||
| type LabelName string | ||||
|  | ||||
| // IsValid is true iff the label name matches the pattern of LabelNameRE. This | ||||
| // method, however, does not use LabelNameRE for the check but a much faster | ||||
| // hardcoded implementation. | ||||
| func (ln LabelName) IsValid() bool { | ||||
| 	if len(ln) == 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 	for i, b := range ln { | ||||
| 		if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // UnmarshalYAML implements the yaml.Unmarshaler interface. | ||||
| func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error { | ||||
| 	var s string | ||||
| 	if err := unmarshal(&s); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if !LabelName(s).IsValid() { | ||||
| 		return fmt.Errorf("%q is not a valid label name", s) | ||||
| 	} | ||||
| 	*ln = LabelName(s) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements the json.Unmarshaler interface. | ||||
| func (ln *LabelName) UnmarshalJSON(b []byte) error { | ||||
| 	var s string | ||||
| 	if err := json.Unmarshal(b, &s); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if !LabelName(s).IsValid() { | ||||
| 		return fmt.Errorf("%q is not a valid label name", s) | ||||
| 	} | ||||
| 	*ln = LabelName(s) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // LabelNames is a sortable LabelName slice. In implements sort.Interface. | ||||
| type LabelNames []LabelName | ||||
|  | ||||
| func (l LabelNames) Len() int { | ||||
| 	return len(l) | ||||
| } | ||||
|  | ||||
| func (l LabelNames) Less(i, j int) bool { | ||||
| 	return l[i] < l[j] | ||||
| } | ||||
|  | ||||
| func (l LabelNames) Swap(i, j int) { | ||||
| 	l[i], l[j] = l[j], l[i] | ||||
| } | ||||
|  | ||||
| func (l LabelNames) String() string { | ||||
| 	labelStrings := make([]string, 0, len(l)) | ||||
| 	for _, label := range l { | ||||
| 		labelStrings = append(labelStrings, string(label)) | ||||
| 	} | ||||
| 	return strings.Join(labelStrings, ", ") | ||||
| } | ||||
|  | ||||
| // A LabelValue is an associated value for a LabelName. | ||||
| type LabelValue string | ||||
|  | ||||
| // IsValid returns true iff the string is a valid UTF8. | ||||
| func (lv LabelValue) IsValid() bool { | ||||
| 	return utf8.ValidString(string(lv)) | ||||
| } | ||||
|  | ||||
| // LabelValues is a sortable LabelValue slice. It implements sort.Interface. | ||||
| type LabelValues []LabelValue | ||||
|  | ||||
| func (l LabelValues) Len() int { | ||||
| 	return len(l) | ||||
| } | ||||
|  | ||||
| func (l LabelValues) Less(i, j int) bool { | ||||
| 	return string(l[i]) < string(l[j]) | ||||
| } | ||||
|  | ||||
| func (l LabelValues) Swap(i, j int) { | ||||
| 	l[i], l[j] = l[j], l[i] | ||||
| } | ||||
|  | ||||
| // LabelPair pairs a name with a value. | ||||
| type LabelPair struct { | ||||
| 	Name  LabelName | ||||
| 	Value LabelValue | ||||
| } | ||||
|  | ||||
| // LabelPairs is a sortable slice of LabelPair pointers. It implements | ||||
| // sort.Interface. | ||||
| type LabelPairs []*LabelPair | ||||
|  | ||||
| func (l LabelPairs) Len() int { | ||||
| 	return len(l) | ||||
| } | ||||
|  | ||||
| func (l LabelPairs) Less(i, j int) bool { | ||||
| 	switch { | ||||
| 	case l[i].Name > l[j].Name: | ||||
| 		return false | ||||
| 	case l[i].Name < l[j].Name: | ||||
| 		return true | ||||
| 	case l[i].Value > l[j].Value: | ||||
| 		return false | ||||
| 	case l[i].Value < l[j].Value: | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (l LabelPairs) Swap(i, j int) { | ||||
| 	l[i], l[j] = l[j], l[i] | ||||
| } | ||||
							
								
								
									
										169
									
								
								vendor/github.com/prometheus/common/model/labelset.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								vendor/github.com/prometheus/common/model/labelset.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // A LabelSet is a collection of LabelName and LabelValue pairs.  The LabelSet | ||||
| // may be fully-qualified down to the point where it may resolve to a single | ||||
| // Metric in the data store or not.  All operations that occur within the realm | ||||
| // of a LabelSet can emit a vector of Metric entities to which the LabelSet may | ||||
| // match. | ||||
| type LabelSet map[LabelName]LabelValue | ||||
|  | ||||
| // Validate checks whether all names and values in the label set | ||||
| // are valid. | ||||
| func (ls LabelSet) Validate() error { | ||||
| 	for ln, lv := range ls { | ||||
| 		if !ln.IsValid() { | ||||
| 			return fmt.Errorf("invalid name %q", ln) | ||||
| 		} | ||||
| 		if !lv.IsValid() { | ||||
| 			return fmt.Errorf("invalid value %q", lv) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Equal returns true iff both label sets have exactly the same key/value pairs. | ||||
| func (ls LabelSet) Equal(o LabelSet) bool { | ||||
| 	if len(ls) != len(o) { | ||||
| 		return false | ||||
| 	} | ||||
| 	for ln, lv := range ls { | ||||
| 		olv, ok := o[ln] | ||||
| 		if !ok { | ||||
| 			return false | ||||
| 		} | ||||
| 		if olv != lv { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // Before compares the metrics, using the following criteria: | ||||
| // | ||||
| // If m has fewer labels than o, it is before o. If it has more, it is not. | ||||
| // | ||||
| // If the number of labels is the same, the superset of all label names is | ||||
| // sorted alphanumerically. The first differing label pair found in that order | ||||
| // determines the outcome: If the label does not exist at all in m, then m is | ||||
| // before o, and vice versa. Otherwise the label value is compared | ||||
| // alphanumerically. | ||||
| // | ||||
| // If m and o are equal, the method returns false. | ||||
| func (ls LabelSet) Before(o LabelSet) bool { | ||||
| 	if len(ls) < len(o) { | ||||
| 		return true | ||||
| 	} | ||||
| 	if len(ls) > len(o) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	lns := make(LabelNames, 0, len(ls)+len(o)) | ||||
| 	for ln := range ls { | ||||
| 		lns = append(lns, ln) | ||||
| 	} | ||||
| 	for ln := range o { | ||||
| 		lns = append(lns, ln) | ||||
| 	} | ||||
| 	// It's probably not worth it to de-dup lns. | ||||
| 	sort.Sort(lns) | ||||
| 	for _, ln := range lns { | ||||
| 		mlv, ok := ls[ln] | ||||
| 		if !ok { | ||||
| 			return true | ||||
| 		} | ||||
| 		olv, ok := o[ln] | ||||
| 		if !ok { | ||||
| 			return false | ||||
| 		} | ||||
| 		if mlv < olv { | ||||
| 			return true | ||||
| 		} | ||||
| 		if mlv > olv { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| // Clone returns a copy of the label set. | ||||
| func (ls LabelSet) Clone() LabelSet { | ||||
| 	lsn := make(LabelSet, len(ls)) | ||||
| 	for ln, lv := range ls { | ||||
| 		lsn[ln] = lv | ||||
| 	} | ||||
| 	return lsn | ||||
| } | ||||
|  | ||||
| // Merge is a helper function to non-destructively merge two label sets. | ||||
| func (l LabelSet) Merge(other LabelSet) LabelSet { | ||||
| 	result := make(LabelSet, len(l)) | ||||
|  | ||||
| 	for k, v := range l { | ||||
| 		result[k] = v | ||||
| 	} | ||||
|  | ||||
| 	for k, v := range other { | ||||
| 		result[k] = v | ||||
| 	} | ||||
|  | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func (l LabelSet) String() string { | ||||
| 	lstrs := make([]string, 0, len(l)) | ||||
| 	for l, v := range l { | ||||
| 		lstrs = append(lstrs, fmt.Sprintf("%s=%q", l, v)) | ||||
| 	} | ||||
|  | ||||
| 	sort.Strings(lstrs) | ||||
| 	return fmt.Sprintf("{%s}", strings.Join(lstrs, ", ")) | ||||
| } | ||||
|  | ||||
| // Fingerprint returns the LabelSet's fingerprint. | ||||
| func (ls LabelSet) Fingerprint() Fingerprint { | ||||
| 	return labelSetToFingerprint(ls) | ||||
| } | ||||
|  | ||||
| // FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing | ||||
| // algorithm, which is, however, more susceptible to hash collisions. | ||||
| func (ls LabelSet) FastFingerprint() Fingerprint { | ||||
| 	return labelSetToFastFingerprint(ls) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements the json.Unmarshaler interface. | ||||
| func (l *LabelSet) UnmarshalJSON(b []byte) error { | ||||
| 	var m map[LabelName]LabelValue | ||||
| 	if err := json.Unmarshal(b, &m); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	// encoding/json only unmarshals maps of the form map[string]T. It treats | ||||
| 	// LabelName as a string and does not call its UnmarshalJSON method. | ||||
| 	// Thus, we have to replicate the behavior here. | ||||
| 	for ln := range m { | ||||
| 		if !ln.IsValid() { | ||||
| 			return fmt.Errorf("%q is not a valid label name", ln) | ||||
| 		} | ||||
| 	} | ||||
| 	*l = LabelSet(m) | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										102
									
								
								vendor/github.com/prometheus/common/model/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								vendor/github.com/prometheus/common/model/metric.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// MetricNameRE is a regular expression matching valid metric | ||||
| 	// names. Note that the IsValidMetricName function performs the same | ||||
| 	// check but faster than a match with this regular expression. | ||||
| 	MetricNameRE = regexp.MustCompile(`^[a-zA-Z_:][a-zA-Z0-9_:]*$`) | ||||
| ) | ||||
|  | ||||
| // A Metric is similar to a LabelSet, but the key difference is that a Metric is | ||||
| // a singleton and refers to one and only one stream of samples. | ||||
| type Metric LabelSet | ||||
|  | ||||
| // Equal compares the metrics. | ||||
| func (m Metric) Equal(o Metric) bool { | ||||
| 	return LabelSet(m).Equal(LabelSet(o)) | ||||
| } | ||||
|  | ||||
| // Before compares the metrics' underlying label sets. | ||||
| func (m Metric) Before(o Metric) bool { | ||||
| 	return LabelSet(m).Before(LabelSet(o)) | ||||
| } | ||||
|  | ||||
| // Clone returns a copy of the Metric. | ||||
| func (m Metric) Clone() Metric { | ||||
| 	clone := make(Metric, len(m)) | ||||
| 	for k, v := range m { | ||||
| 		clone[k] = v | ||||
| 	} | ||||
| 	return clone | ||||
| } | ||||
|  | ||||
| func (m Metric) String() string { | ||||
| 	metricName, hasName := m[MetricNameLabel] | ||||
| 	numLabels := len(m) - 1 | ||||
| 	if !hasName { | ||||
| 		numLabels = len(m) | ||||
| 	} | ||||
| 	labelStrings := make([]string, 0, numLabels) | ||||
| 	for label, value := range m { | ||||
| 		if label != MetricNameLabel { | ||||
| 			labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	switch numLabels { | ||||
| 	case 0: | ||||
| 		if hasName { | ||||
| 			return string(metricName) | ||||
| 		} | ||||
| 		return "{}" | ||||
| 	default: | ||||
| 		sort.Strings(labelStrings) | ||||
| 		return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", ")) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Fingerprint returns a Metric's Fingerprint. | ||||
| func (m Metric) Fingerprint() Fingerprint { | ||||
| 	return LabelSet(m).Fingerprint() | ||||
| } | ||||
|  | ||||
| // FastFingerprint returns a Metric's Fingerprint calculated by a faster hashing | ||||
| // algorithm, which is, however, more susceptible to hash collisions. | ||||
| func (m Metric) FastFingerprint() Fingerprint { | ||||
| 	return LabelSet(m).FastFingerprint() | ||||
| } | ||||
|  | ||||
| // IsValidMetricName returns true iff name matches the pattern of MetricNameRE. | ||||
| // This function, however, does not use MetricNameRE for the check but a much | ||||
| // faster hardcoded implementation. | ||||
| func IsValidMetricName(n LabelValue) bool { | ||||
| 	if len(n) == 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 	for i, b := range n { | ||||
| 		if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == ':' || (b >= '0' && b <= '9' && i > 0)) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
							
								
								
									
										16
									
								
								vendor/github.com/prometheus/common/model/model.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/prometheus/common/model/model.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| // Package model contains common data structures that are shared across | ||||
| // Prometheus components and libraries. | ||||
| package model | ||||
							
								
								
									
										144
									
								
								vendor/github.com/prometheus/common/model/signature.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								vendor/github.com/prometheus/common/model/signature.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| // Copyright 2014 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"sort" | ||||
| ) | ||||
|  | ||||
| // SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is | ||||
| // used to separate label names, label values, and other strings from each other | ||||
| // when calculating their combined hash value (aka signature aka fingerprint). | ||||
| const SeparatorByte byte = 255 | ||||
|  | ||||
| var ( | ||||
| 	// cache the signature of an empty label set. | ||||
| 	emptyLabelSignature = hashNew() | ||||
| ) | ||||
|  | ||||
| // LabelsToSignature returns a quasi-unique signature (i.e., fingerprint) for a | ||||
| // given label set. (Collisions are possible but unlikely if the number of label | ||||
| // sets the function is applied to is small.) | ||||
| func LabelsToSignature(labels map[string]string) uint64 { | ||||
| 	if len(labels) == 0 { | ||||
| 		return emptyLabelSignature | ||||
| 	} | ||||
|  | ||||
| 	labelNames := make([]string, 0, len(labels)) | ||||
| 	for labelName := range labels { | ||||
| 		labelNames = append(labelNames, labelName) | ||||
| 	} | ||||
| 	sort.Strings(labelNames) | ||||
|  | ||||
| 	sum := hashNew() | ||||
| 	for _, labelName := range labelNames { | ||||
| 		sum = hashAdd(sum, labelName) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 		sum = hashAdd(sum, labels[labelName]) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 	} | ||||
| 	return sum | ||||
| } | ||||
|  | ||||
| // labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as | ||||
| // parameter (rather than a label map) and returns a Fingerprint. | ||||
| func labelSetToFingerprint(ls LabelSet) Fingerprint { | ||||
| 	if len(ls) == 0 { | ||||
| 		return Fingerprint(emptyLabelSignature) | ||||
| 	} | ||||
|  | ||||
| 	labelNames := make(LabelNames, 0, len(ls)) | ||||
| 	for labelName := range ls { | ||||
| 		labelNames = append(labelNames, labelName) | ||||
| 	} | ||||
| 	sort.Sort(labelNames) | ||||
|  | ||||
| 	sum := hashNew() | ||||
| 	for _, labelName := range labelNames { | ||||
| 		sum = hashAdd(sum, string(labelName)) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 		sum = hashAdd(sum, string(ls[labelName])) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 	} | ||||
| 	return Fingerprint(sum) | ||||
| } | ||||
|  | ||||
| // labelSetToFastFingerprint works similar to labelSetToFingerprint but uses a | ||||
| // faster and less allocation-heavy hash function, which is more susceptible to | ||||
| // create hash collisions. Therefore, collision detection should be applied. | ||||
| func labelSetToFastFingerprint(ls LabelSet) Fingerprint { | ||||
| 	if len(ls) == 0 { | ||||
| 		return Fingerprint(emptyLabelSignature) | ||||
| 	} | ||||
|  | ||||
| 	var result uint64 | ||||
| 	for labelName, labelValue := range ls { | ||||
| 		sum := hashNew() | ||||
| 		sum = hashAdd(sum, string(labelName)) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 		sum = hashAdd(sum, string(labelValue)) | ||||
| 		result ^= sum | ||||
| 	} | ||||
| 	return Fingerprint(result) | ||||
| } | ||||
|  | ||||
| // SignatureForLabels works like LabelsToSignature but takes a Metric as | ||||
| // parameter (rather than a label map) and only includes the labels with the | ||||
| // specified LabelNames into the signature calculation. The labels passed in | ||||
| // will be sorted by this function. | ||||
| func SignatureForLabels(m Metric, labels ...LabelName) uint64 { | ||||
| 	if len(labels) == 0 { | ||||
| 		return emptyLabelSignature | ||||
| 	} | ||||
|  | ||||
| 	sort.Sort(LabelNames(labels)) | ||||
|  | ||||
| 	sum := hashNew() | ||||
| 	for _, label := range labels { | ||||
| 		sum = hashAdd(sum, string(label)) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 		sum = hashAdd(sum, string(m[label])) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 	} | ||||
| 	return sum | ||||
| } | ||||
|  | ||||
| // SignatureWithoutLabels works like LabelsToSignature but takes a Metric as | ||||
| // parameter (rather than a label map) and excludes the labels with any of the | ||||
| // specified LabelNames from the signature calculation. | ||||
| func SignatureWithoutLabels(m Metric, labels map[LabelName]struct{}) uint64 { | ||||
| 	if len(m) == 0 { | ||||
| 		return emptyLabelSignature | ||||
| 	} | ||||
|  | ||||
| 	labelNames := make(LabelNames, 0, len(m)) | ||||
| 	for labelName := range m { | ||||
| 		if _, exclude := labels[labelName]; !exclude { | ||||
| 			labelNames = append(labelNames, labelName) | ||||
| 		} | ||||
| 	} | ||||
| 	if len(labelNames) == 0 { | ||||
| 		return emptyLabelSignature | ||||
| 	} | ||||
| 	sort.Sort(labelNames) | ||||
|  | ||||
| 	sum := hashNew() | ||||
| 	for _, labelName := range labelNames { | ||||
| 		sum = hashAdd(sum, string(labelName)) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 		sum = hashAdd(sum, string(m[labelName])) | ||||
| 		sum = hashAddByte(sum, SeparatorByte) | ||||
| 	} | ||||
| 	return sum | ||||
| } | ||||
							
								
								
									
										106
									
								
								vendor/github.com/prometheus/common/model/silence.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/prometheus/common/model/silence.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| // Copyright 2015 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Matcher describes a matches the value of a given label. | ||||
| type Matcher struct { | ||||
| 	Name    LabelName `json:"name"` | ||||
| 	Value   string    `json:"value"` | ||||
| 	IsRegex bool      `json:"isRegex"` | ||||
| } | ||||
|  | ||||
| func (m *Matcher) UnmarshalJSON(b []byte) error { | ||||
| 	type plain Matcher | ||||
| 	if err := json.Unmarshal(b, (*plain)(m)); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if len(m.Name) == 0 { | ||||
| 		return fmt.Errorf("label name in matcher must not be empty") | ||||
| 	} | ||||
| 	if m.IsRegex { | ||||
| 		if _, err := regexp.Compile(m.Value); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Validate returns true iff all fields of the matcher have valid values. | ||||
| func (m *Matcher) Validate() error { | ||||
| 	if !m.Name.IsValid() { | ||||
| 		return fmt.Errorf("invalid name %q", m.Name) | ||||
| 	} | ||||
| 	if m.IsRegex { | ||||
| 		if _, err := regexp.Compile(m.Value); err != nil { | ||||
| 			return fmt.Errorf("invalid regular expression %q", m.Value) | ||||
| 		} | ||||
| 	} else if !LabelValue(m.Value).IsValid() || len(m.Value) == 0 { | ||||
| 		return fmt.Errorf("invalid value %q", m.Value) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Silence defines the representation of a silence definition in the Prometheus | ||||
| // eco-system. | ||||
| type Silence struct { | ||||
| 	ID uint64 `json:"id,omitempty"` | ||||
|  | ||||
| 	Matchers []*Matcher `json:"matchers"` | ||||
|  | ||||
| 	StartsAt time.Time `json:"startsAt"` | ||||
| 	EndsAt   time.Time `json:"endsAt"` | ||||
|  | ||||
| 	CreatedAt time.Time `json:"createdAt,omitempty"` | ||||
| 	CreatedBy string    `json:"createdBy"` | ||||
| 	Comment   string    `json:"comment,omitempty"` | ||||
| } | ||||
|  | ||||
| // Validate returns true iff all fields of the silence have valid values. | ||||
| func (s *Silence) Validate() error { | ||||
| 	if len(s.Matchers) == 0 { | ||||
| 		return fmt.Errorf("at least one matcher required") | ||||
| 	} | ||||
| 	for _, m := range s.Matchers { | ||||
| 		if err := m.Validate(); err != nil { | ||||
| 			return fmt.Errorf("invalid matcher: %s", err) | ||||
| 		} | ||||
| 	} | ||||
| 	if s.StartsAt.IsZero() { | ||||
| 		return fmt.Errorf("start time missing") | ||||
| 	} | ||||
| 	if s.EndsAt.IsZero() { | ||||
| 		return fmt.Errorf("end time missing") | ||||
| 	} | ||||
| 	if s.EndsAt.Before(s.StartsAt) { | ||||
| 		return fmt.Errorf("start time must be before end time") | ||||
| 	} | ||||
| 	if s.CreatedBy == "" { | ||||
| 		return fmt.Errorf("creator information missing") | ||||
| 	} | ||||
| 	if s.Comment == "" { | ||||
| 		return fmt.Errorf("comment missing") | ||||
| 	} | ||||
| 	if s.CreatedAt.IsZero() { | ||||
| 		return fmt.Errorf("creation timestamp missing") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										317
									
								
								vendor/github.com/prometheus/common/model/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										317
									
								
								vendor/github.com/prometheus/common/model/time.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,317 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"regexp" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// MinimumTick is the minimum supported time resolution. This has to be | ||||
| 	// at least time.Second in order for the code below to work. | ||||
| 	minimumTick = time.Millisecond | ||||
| 	// second is the Time duration equivalent to one second. | ||||
| 	second = int64(time.Second / minimumTick) | ||||
| 	// The number of nanoseconds per minimum tick. | ||||
| 	nanosPerTick = int64(minimumTick / time.Nanosecond) | ||||
|  | ||||
| 	// Earliest is the earliest Time representable. Handy for | ||||
| 	// initializing a high watermark. | ||||
| 	Earliest = Time(math.MinInt64) | ||||
| 	// Latest is the latest Time representable. Handy for initializing | ||||
| 	// a low watermark. | ||||
| 	Latest = Time(math.MaxInt64) | ||||
| ) | ||||
|  | ||||
| // Time is the number of milliseconds since the epoch | ||||
| // (1970-01-01 00:00 UTC) excluding leap seconds. | ||||
| type Time int64 | ||||
|  | ||||
| // Interval describes an interval between two timestamps. | ||||
| type Interval struct { | ||||
| 	Start, End Time | ||||
| } | ||||
|  | ||||
| // Now returns the current time as a Time. | ||||
| func Now() Time { | ||||
| 	return TimeFromUnixNano(time.Now().UnixNano()) | ||||
| } | ||||
|  | ||||
| // TimeFromUnix returns the Time equivalent to the Unix Time t | ||||
| // provided in seconds. | ||||
| func TimeFromUnix(t int64) Time { | ||||
| 	return Time(t * second) | ||||
| } | ||||
|  | ||||
| // TimeFromUnixNano returns the Time equivalent to the Unix Time | ||||
| // t provided in nanoseconds. | ||||
| func TimeFromUnixNano(t int64) Time { | ||||
| 	return Time(t / nanosPerTick) | ||||
| } | ||||
|  | ||||
| // Equal reports whether two Times represent the same instant. | ||||
| func (t Time) Equal(o Time) bool { | ||||
| 	return t == o | ||||
| } | ||||
|  | ||||
| // Before reports whether the Time t is before o. | ||||
| func (t Time) Before(o Time) bool { | ||||
| 	return t < o | ||||
| } | ||||
|  | ||||
| // After reports whether the Time t is after o. | ||||
| func (t Time) After(o Time) bool { | ||||
| 	return t > o | ||||
| } | ||||
|  | ||||
| // Add returns the Time t + d. | ||||
| func (t Time) Add(d time.Duration) Time { | ||||
| 	return t + Time(d/minimumTick) | ||||
| } | ||||
|  | ||||
| // Sub returns the Duration t - o. | ||||
| func (t Time) Sub(o Time) time.Duration { | ||||
| 	return time.Duration(t-o) * minimumTick | ||||
| } | ||||
|  | ||||
| // Time returns the time.Time representation of t. | ||||
| func (t Time) Time() time.Time { | ||||
| 	return time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick) | ||||
| } | ||||
|  | ||||
| // Unix returns t as a Unix time, the number of seconds elapsed | ||||
| // since January 1, 1970 UTC. | ||||
| func (t Time) Unix() int64 { | ||||
| 	return int64(t) / second | ||||
| } | ||||
|  | ||||
| // UnixNano returns t as a Unix time, the number of nanoseconds elapsed | ||||
| // since January 1, 1970 UTC. | ||||
| func (t Time) UnixNano() int64 { | ||||
| 	return int64(t) * nanosPerTick | ||||
| } | ||||
|  | ||||
| // The number of digits after the dot. | ||||
| var dotPrecision = int(math.Log10(float64(second))) | ||||
|  | ||||
| // String returns a string representation of the Time. | ||||
| func (t Time) String() string { | ||||
| 	return strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64) | ||||
| } | ||||
|  | ||||
| // MarshalJSON implements the json.Marshaler interface. | ||||
| func (t Time) MarshalJSON() ([]byte, error) { | ||||
| 	return []byte(t.String()), nil | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements the json.Unmarshaler interface. | ||||
| func (t *Time) UnmarshalJSON(b []byte) error { | ||||
| 	p := strings.Split(string(b), ".") | ||||
| 	switch len(p) { | ||||
| 	case 1: | ||||
| 		v, err := strconv.ParseInt(string(p[0]), 10, 64) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		*t = Time(v * second) | ||||
|  | ||||
| 	case 2: | ||||
| 		v, err := strconv.ParseInt(string(p[0]), 10, 64) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		v *= second | ||||
|  | ||||
| 		prec := dotPrecision - len(p[1]) | ||||
| 		if prec < 0 { | ||||
| 			p[1] = p[1][:dotPrecision] | ||||
| 		} else if prec > 0 { | ||||
| 			p[1] = p[1] + strings.Repeat("0", prec) | ||||
| 		} | ||||
|  | ||||
| 		va, err := strconv.ParseInt(p[1], 10, 32) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// If the value was something like -0.1 the negative is lost in the | ||||
| 		// parsing because of the leading zero, this ensures that we capture it. | ||||
| 		if len(p[0]) > 0 && p[0][0] == '-' && v+va > 0 { | ||||
| 			*t = Time(v+va) * -1 | ||||
| 		} else { | ||||
| 			*t = Time(v + va) | ||||
| 		} | ||||
|  | ||||
| 	default: | ||||
| 		return fmt.Errorf("invalid time %q", string(b)) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Duration wraps time.Duration. It is used to parse the custom duration format | ||||
| // from YAML. | ||||
| // This type should not propagate beyond the scope of input/output processing. | ||||
| type Duration time.Duration | ||||
|  | ||||
| // Set implements pflag/flag.Value | ||||
| func (d *Duration) Set(s string) error { | ||||
| 	var err error | ||||
| 	*d, err = ParseDuration(s) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // Type implements pflag.Value | ||||
| func (d *Duration) Type() string { | ||||
| 	return "duration" | ||||
| } | ||||
|  | ||||
| var durationRE = regexp.MustCompile("^(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?$") | ||||
|  | ||||
| // ParseDuration parses a string into a time.Duration, assuming that a year | ||||
| // always has 365d, a week always has 7d, and a day always has 24h. | ||||
| func ParseDuration(durationStr string) (Duration, error) { | ||||
| 	switch durationStr { | ||||
| 	case "0": | ||||
| 		// Allow 0 without a unit. | ||||
| 		return 0, nil | ||||
| 	case "": | ||||
| 		return 0, errors.New("empty duration string") | ||||
| 	} | ||||
| 	matches := durationRE.FindStringSubmatch(durationStr) | ||||
| 	if matches == nil { | ||||
| 		return 0, fmt.Errorf("not a valid duration string: %q", durationStr) | ||||
| 	} | ||||
| 	var dur time.Duration | ||||
|  | ||||
| 	// Parse the match at pos `pos` in the regex and use `mult` to turn that | ||||
| 	// into ms, then add that value to the total parsed duration. | ||||
| 	var overflowErr error | ||||
| 	m := func(pos int, mult time.Duration) { | ||||
| 		if matches[pos] == "" { | ||||
| 			return | ||||
| 		} | ||||
| 		n, _ := strconv.Atoi(matches[pos]) | ||||
|  | ||||
| 		// Check if the provided duration overflows time.Duration (> ~ 290years). | ||||
| 		if n > int((1<<63-1)/mult/time.Millisecond) { | ||||
| 			overflowErr = errors.New("duration out of range") | ||||
| 		} | ||||
| 		d := time.Duration(n) * time.Millisecond | ||||
| 		dur += d * mult | ||||
|  | ||||
| 		if dur < 0 { | ||||
| 			overflowErr = errors.New("duration out of range") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	m(2, 1000*60*60*24*365) // y | ||||
| 	m(4, 1000*60*60*24*7)   // w | ||||
| 	m(6, 1000*60*60*24)     // d | ||||
| 	m(8, 1000*60*60)        // h | ||||
| 	m(10, 1000*60)          // m | ||||
| 	m(12, 1000)             // s | ||||
| 	m(14, 1)                // ms | ||||
|  | ||||
| 	return Duration(dur), overflowErr | ||||
| } | ||||
|  | ||||
| func (d Duration) String() string { | ||||
| 	var ( | ||||
| 		ms = int64(time.Duration(d) / time.Millisecond) | ||||
| 		r  = "" | ||||
| 	) | ||||
| 	if ms == 0 { | ||||
| 		return "0s" | ||||
| 	} | ||||
|  | ||||
| 	f := func(unit string, mult int64, exact bool) { | ||||
| 		if exact && ms%mult != 0 { | ||||
| 			return | ||||
| 		} | ||||
| 		if v := ms / mult; v > 0 { | ||||
| 			r += fmt.Sprintf("%d%s", v, unit) | ||||
| 			ms -= v * mult | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Only format years and weeks if the remainder is zero, as it is often | ||||
| 	// easier to read 90d than 12w6d. | ||||
| 	f("y", 1000*60*60*24*365, true) | ||||
| 	f("w", 1000*60*60*24*7, true) | ||||
|  | ||||
| 	f("d", 1000*60*60*24, false) | ||||
| 	f("h", 1000*60*60, false) | ||||
| 	f("m", 1000*60, false) | ||||
| 	f("s", 1000, false) | ||||
| 	f("ms", 1, false) | ||||
|  | ||||
| 	return r | ||||
| } | ||||
|  | ||||
| // MarshalJSON implements the json.Marshaler interface. | ||||
| func (d Duration) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(d.String()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements the json.Unmarshaler interface. | ||||
| func (d *Duration) UnmarshalJSON(bytes []byte) error { | ||||
| 	var s string | ||||
| 	if err := json.Unmarshal(bytes, &s); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	dur, err := ParseDuration(s) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*d = dur | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // MarshalText implements the encoding.TextMarshaler interface. | ||||
| func (d *Duration) MarshalText() ([]byte, error) { | ||||
| 	return []byte(d.String()), nil | ||||
| } | ||||
|  | ||||
| // UnmarshalText implements the encoding.TextUnmarshaler interface. | ||||
| func (d *Duration) UnmarshalText(text []byte) error { | ||||
| 	var err error | ||||
| 	*d, err = ParseDuration(string(text)) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // MarshalYAML implements the yaml.Marshaler interface. | ||||
| func (d Duration) MarshalYAML() (interface{}, error) { | ||||
| 	return d.String(), nil | ||||
| } | ||||
|  | ||||
| // UnmarshalYAML implements the yaml.Unmarshaler interface. | ||||
| func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error { | ||||
| 	var s string | ||||
| 	if err := unmarshal(&s); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	dur, err := ParseDuration(s) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*d = dur | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										416
									
								
								vendor/github.com/prometheus/common/model/value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										416
									
								
								vendor/github.com/prometheus/common/model/value.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,416 @@ | ||||
| // Copyright 2013 The Prometheus Authors | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package model | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"math" | ||||
| 	"sort" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a | ||||
| 	// non-existing sample pair. It is a SamplePair with timestamp Earliest and | ||||
| 	// value 0.0. Note that the natural zero value of SamplePair has a timestamp | ||||
| 	// of 0, which is possible to appear in a real SamplePair and thus not | ||||
| 	// suitable to signal a non-existing SamplePair. | ||||
| 	ZeroSamplePair = SamplePair{Timestamp: Earliest} | ||||
|  | ||||
| 	// ZeroSample is the pseudo zero-value of Sample used to signal a | ||||
| 	// non-existing sample. It is a Sample with timestamp Earliest, value 0.0, | ||||
| 	// and metric nil. Note that the natural zero value of Sample has a timestamp | ||||
| 	// of 0, which is possible to appear in a real Sample and thus not suitable | ||||
| 	// to signal a non-existing Sample. | ||||
| 	ZeroSample = Sample{Timestamp: Earliest} | ||||
| ) | ||||
|  | ||||
| // A SampleValue is a representation of a value for a given sample at a given | ||||
| // time. | ||||
| type SampleValue float64 | ||||
|  | ||||
| // MarshalJSON implements json.Marshaler. | ||||
| func (v SampleValue) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(v.String()) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements json.Unmarshaler. | ||||
| func (v *SampleValue) UnmarshalJSON(b []byte) error { | ||||
| 	if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' { | ||||
| 		return fmt.Errorf("sample value must be a quoted string") | ||||
| 	} | ||||
| 	f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	*v = SampleValue(f) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Equal returns true if the value of v and o is equal or if both are NaN. Note | ||||
| // that v==o is false if both are NaN. If you want the conventional float | ||||
| // behavior, use == to compare two SampleValues. | ||||
| func (v SampleValue) Equal(o SampleValue) bool { | ||||
| 	if v == o { | ||||
| 		return true | ||||
| 	} | ||||
| 	return math.IsNaN(float64(v)) && math.IsNaN(float64(o)) | ||||
| } | ||||
|  | ||||
| func (v SampleValue) String() string { | ||||
| 	return strconv.FormatFloat(float64(v), 'f', -1, 64) | ||||
| } | ||||
|  | ||||
| // SamplePair pairs a SampleValue with a Timestamp. | ||||
| type SamplePair struct { | ||||
| 	Timestamp Time | ||||
| 	Value     SampleValue | ||||
| } | ||||
|  | ||||
| // MarshalJSON implements json.Marshaler. | ||||
| func (s SamplePair) MarshalJSON() ([]byte, error) { | ||||
| 	t, err := json.Marshal(s.Timestamp) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	v, err := json.Marshal(s.Value) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements json.Unmarshaler. | ||||
| func (s *SamplePair) UnmarshalJSON(b []byte) error { | ||||
| 	v := [...]json.Unmarshaler{&s.Timestamp, &s.Value} | ||||
| 	return json.Unmarshal(b, &v) | ||||
| } | ||||
|  | ||||
| // Equal returns true if this SamplePair and o have equal Values and equal | ||||
| // Timestamps. The semantics of Value equality is defined by SampleValue.Equal. | ||||
| func (s *SamplePair) Equal(o *SamplePair) bool { | ||||
| 	return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp)) | ||||
| } | ||||
|  | ||||
| func (s SamplePair) String() string { | ||||
| 	return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp) | ||||
| } | ||||
|  | ||||
| // Sample is a sample pair associated with a metric. | ||||
| type Sample struct { | ||||
| 	Metric    Metric      `json:"metric"` | ||||
| 	Value     SampleValue `json:"value"` | ||||
| 	Timestamp Time        `json:"timestamp"` | ||||
| } | ||||
|  | ||||
| // Equal compares first the metrics, then the timestamp, then the value. The | ||||
| // semantics of value equality is defined by SampleValue.Equal. | ||||
| func (s *Sample) Equal(o *Sample) bool { | ||||
| 	if s == o { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	if !s.Metric.Equal(o.Metric) { | ||||
| 		return false | ||||
| 	} | ||||
| 	if !s.Timestamp.Equal(o.Timestamp) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return s.Value.Equal(o.Value) | ||||
| } | ||||
|  | ||||
| func (s Sample) String() string { | ||||
| 	return fmt.Sprintf("%s => %s", s.Metric, SamplePair{ | ||||
| 		Timestamp: s.Timestamp, | ||||
| 		Value:     s.Value, | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // MarshalJSON implements json.Marshaler. | ||||
| func (s Sample) MarshalJSON() ([]byte, error) { | ||||
| 	v := struct { | ||||
| 		Metric Metric     `json:"metric"` | ||||
| 		Value  SamplePair `json:"value"` | ||||
| 	}{ | ||||
| 		Metric: s.Metric, | ||||
| 		Value: SamplePair{ | ||||
| 			Timestamp: s.Timestamp, | ||||
| 			Value:     s.Value, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	return json.Marshal(&v) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements json.Unmarshaler. | ||||
| func (s *Sample) UnmarshalJSON(b []byte) error { | ||||
| 	v := struct { | ||||
| 		Metric Metric     `json:"metric"` | ||||
| 		Value  SamplePair `json:"value"` | ||||
| 	}{ | ||||
| 		Metric: s.Metric, | ||||
| 		Value: SamplePair{ | ||||
| 			Timestamp: s.Timestamp, | ||||
| 			Value:     s.Value, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	s.Metric = v.Metric | ||||
| 	s.Timestamp = v.Value.Timestamp | ||||
| 	s.Value = v.Value.Value | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Samples is a sortable Sample slice. It implements sort.Interface. | ||||
| type Samples []*Sample | ||||
|  | ||||
| func (s Samples) Len() int { | ||||
| 	return len(s) | ||||
| } | ||||
|  | ||||
| // Less compares first the metrics, then the timestamp. | ||||
| func (s Samples) Less(i, j int) bool { | ||||
| 	switch { | ||||
| 	case s[i].Metric.Before(s[j].Metric): | ||||
| 		return true | ||||
| 	case s[j].Metric.Before(s[i].Metric): | ||||
| 		return false | ||||
| 	case s[i].Timestamp.Before(s[j].Timestamp): | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s Samples) Swap(i, j int) { | ||||
| 	s[i], s[j] = s[j], s[i] | ||||
| } | ||||
|  | ||||
| // Equal compares two sets of samples and returns true if they are equal. | ||||
| func (s Samples) Equal(o Samples) bool { | ||||
| 	if len(s) != len(o) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	for i, sample := range s { | ||||
| 		if !sample.Equal(o[i]) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // SampleStream is a stream of Values belonging to an attached COWMetric. | ||||
| type SampleStream struct { | ||||
| 	Metric Metric       `json:"metric"` | ||||
| 	Values []SamplePair `json:"values"` | ||||
| } | ||||
|  | ||||
| func (ss SampleStream) String() string { | ||||
| 	vals := make([]string, len(ss.Values)) | ||||
| 	for i, v := range ss.Values { | ||||
| 		vals[i] = v.String() | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n")) | ||||
| } | ||||
|  | ||||
| // Value is a generic interface for values resulting from a query evaluation. | ||||
| type Value interface { | ||||
| 	Type() ValueType | ||||
| 	String() string | ||||
| } | ||||
|  | ||||
| func (Matrix) Type() ValueType  { return ValMatrix } | ||||
| func (Vector) Type() ValueType  { return ValVector } | ||||
| func (*Scalar) Type() ValueType { return ValScalar } | ||||
| func (*String) Type() ValueType { return ValString } | ||||
|  | ||||
| type ValueType int | ||||
|  | ||||
| const ( | ||||
| 	ValNone ValueType = iota | ||||
| 	ValScalar | ||||
| 	ValVector | ||||
| 	ValMatrix | ||||
| 	ValString | ||||
| ) | ||||
|  | ||||
| // MarshalJSON implements json.Marshaler. | ||||
| func (et ValueType) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(et.String()) | ||||
| } | ||||
|  | ||||
| func (et *ValueType) UnmarshalJSON(b []byte) error { | ||||
| 	var s string | ||||
| 	if err := json.Unmarshal(b, &s); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	switch s { | ||||
| 	case "<ValNone>": | ||||
| 		*et = ValNone | ||||
| 	case "scalar": | ||||
| 		*et = ValScalar | ||||
| 	case "vector": | ||||
| 		*et = ValVector | ||||
| 	case "matrix": | ||||
| 		*et = ValMatrix | ||||
| 	case "string": | ||||
| 		*et = ValString | ||||
| 	default: | ||||
| 		return fmt.Errorf("unknown value type %q", s) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (e ValueType) String() string { | ||||
| 	switch e { | ||||
| 	case ValNone: | ||||
| 		return "<ValNone>" | ||||
| 	case ValScalar: | ||||
| 		return "scalar" | ||||
| 	case ValVector: | ||||
| 		return "vector" | ||||
| 	case ValMatrix: | ||||
| 		return "matrix" | ||||
| 	case ValString: | ||||
| 		return "string" | ||||
| 	} | ||||
| 	panic("ValueType.String: unhandled value type") | ||||
| } | ||||
|  | ||||
| // Scalar is a scalar value evaluated at the set timestamp. | ||||
| type Scalar struct { | ||||
| 	Value     SampleValue `json:"value"` | ||||
| 	Timestamp Time        `json:"timestamp"` | ||||
| } | ||||
|  | ||||
| func (s Scalar) String() string { | ||||
| 	return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp) | ||||
| } | ||||
|  | ||||
| // MarshalJSON implements json.Marshaler. | ||||
| func (s Scalar) MarshalJSON() ([]byte, error) { | ||||
| 	v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64) | ||||
| 	return json.Marshal([...]interface{}{s.Timestamp, string(v)}) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements json.Unmarshaler. | ||||
| func (s *Scalar) UnmarshalJSON(b []byte) error { | ||||
| 	var f string | ||||
| 	v := [...]interface{}{&s.Timestamp, &f} | ||||
|  | ||||
| 	if err := json.Unmarshal(b, &v); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	value, err := strconv.ParseFloat(f, 64) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("error parsing sample value: %s", err) | ||||
| 	} | ||||
| 	s.Value = SampleValue(value) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // String is a string value evaluated at the set timestamp. | ||||
| type String struct { | ||||
| 	Value     string `json:"value"` | ||||
| 	Timestamp Time   `json:"timestamp"` | ||||
| } | ||||
|  | ||||
| func (s *String) String() string { | ||||
| 	return s.Value | ||||
| } | ||||
|  | ||||
| // MarshalJSON implements json.Marshaler. | ||||
| func (s String) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal([]interface{}{s.Timestamp, s.Value}) | ||||
| } | ||||
|  | ||||
| // UnmarshalJSON implements json.Unmarshaler. | ||||
| func (s *String) UnmarshalJSON(b []byte) error { | ||||
| 	v := [...]interface{}{&s.Timestamp, &s.Value} | ||||
| 	return json.Unmarshal(b, &v) | ||||
| } | ||||
|  | ||||
| // Vector is basically only an alias for Samples, but the | ||||
| // contract is that in a Vector, all Samples have the same timestamp. | ||||
| type Vector []*Sample | ||||
|  | ||||
| func (vec Vector) String() string { | ||||
| 	entries := make([]string, len(vec)) | ||||
| 	for i, s := range vec { | ||||
| 		entries[i] = s.String() | ||||
| 	} | ||||
| 	return strings.Join(entries, "\n") | ||||
| } | ||||
|  | ||||
| func (vec Vector) Len() int      { return len(vec) } | ||||
| func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] } | ||||
|  | ||||
| // Less compares first the metrics, then the timestamp. | ||||
| func (vec Vector) Less(i, j int) bool { | ||||
| 	switch { | ||||
| 	case vec[i].Metric.Before(vec[j].Metric): | ||||
| 		return true | ||||
| 	case vec[j].Metric.Before(vec[i].Metric): | ||||
| 		return false | ||||
| 	case vec[i].Timestamp.Before(vec[j].Timestamp): | ||||
| 		return true | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Equal compares two sets of samples and returns true if they are equal. | ||||
| func (vec Vector) Equal(o Vector) bool { | ||||
| 	if len(vec) != len(o) { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	for i, sample := range vec { | ||||
| 		if !sample.Equal(o[i]) { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  | ||||
| // Matrix is a list of time series. | ||||
| type Matrix []*SampleStream | ||||
|  | ||||
| func (m Matrix) Len() int           { return len(m) } | ||||
| func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) } | ||||
| func (m Matrix) Swap(i, j int)      { m[i], m[j] = m[j], m[i] } | ||||
|  | ||||
| func (mat Matrix) String() string { | ||||
| 	matCp := make(Matrix, len(mat)) | ||||
| 	copy(matCp, mat) | ||||
| 	sort.Sort(matCp) | ||||
|  | ||||
| 	strs := make([]string, len(matCp)) | ||||
|  | ||||
| 	for i, ss := range matCp { | ||||
| 		strs[i] = ss.String() | ||||
| 	} | ||||
|  | ||||
| 	return strings.Join(strs, "\n") | ||||
| } | ||||
		Reference in New Issue
	
	Block a user