123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- // 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 (
- separator = []byte{0}
- // 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 := Metric{}
- 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
- }
|