aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/prometheus/client_golang
diff options
context:
space:
mode:
authordependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>2023-09-28 02:08:14 +0000
committerAleksandr Nogikh <nogikh@google.com>2023-09-28 09:53:59 +0000
commitbb894b2a00177e26b616ff31ba61a14dc89f7bd2 (patch)
treecfcec8a22332310adc5e256f99c31751cb8ae9ad /vendor/github.com/prometheus/client_golang
parent746f61e725ad2460e3f101b5e8899105ddea08a1 (diff)
mod: do: bump github.com/prometheus/client_golang from 1.16.0 to 1.17.0
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.16.0 to 1.17.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/v1.17.0/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.16.0...v1.17.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
Diffstat (limited to 'vendor/github.com/prometheus/client_golang')
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/counter.go26
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/desc.go28
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go2
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/gauge.go8
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/histogram.go118
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go2
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/labels.go58
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/metric.go3
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go6
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go9
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/registry.go6
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/summary.go41
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/value.go55
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/vec.go106
14 files changed, 304 insertions, 164 deletions
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go
index 62de4dc59..4ce84e7a8 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/counter.go
@@ -20,6 +20,7 @@ import (
"time"
dto "github.com/prometheus/client_model/go"
+ "google.golang.org/protobuf/types/known/timestamppb"
)
// Counter is a Metric that represents a single numerical value that only ever
@@ -66,7 +67,7 @@ type CounterVecOpts struct {
CounterOpts
// VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Contraint
+ // of labels. Each label value will be constrained with the optional Constraint
// function, if provided.
VariableLabels ConstrainableLabels
}
@@ -90,8 +91,12 @@ func NewCounter(opts CounterOpts) Counter {
nil,
opts.ConstLabels,
)
- result := &counter{desc: desc, labelPairs: desc.constLabelPairs, now: time.Now}
+ if opts.now == nil {
+ opts.now = time.Now
+ }
+ result := &counter{desc: desc, labelPairs: desc.constLabelPairs, now: opts.now}
result.init(result) // Init self-collection.
+ result.createdTs = timestamppb.New(opts.now())
return result
}
@@ -106,10 +111,12 @@ type counter struct {
selfCollector
desc *Desc
+ createdTs *timestamppb.Timestamp
labelPairs []*dto.LabelPair
exemplar atomic.Value // Containing nil or a *dto.Exemplar.
- now func() time.Time // To mock out time.Now() for testing.
+ // now is for testing purposes, by default it's time.Now.
+ now func() time.Time
}
func (c *counter) Desc() *Desc {
@@ -159,8 +166,7 @@ func (c *counter) Write(out *dto.Metric) error {
exemplar = e.(*dto.Exemplar)
}
val := c.get()
-
- return populateMetric(CounterValue, val, c.labelPairs, exemplar, out)
+ return populateMetric(CounterValue, val, c.labelPairs, exemplar, out, c.createdTs)
}
func (c *counter) updateExemplar(v float64, l Labels) {
@@ -200,13 +206,17 @@ func (v2) NewCounterVec(opts CounterVecOpts) *CounterVec {
opts.VariableLabels,
opts.ConstLabels,
)
+ if opts.now == nil {
+ opts.now = time.Now
+ }
return &CounterVec{
MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
- if len(lvs) != len(desc.variableLabels) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), lvs))
+ if len(lvs) != len(desc.variableLabels.names) {
+ panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs))
}
- result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: time.Now}
+ result := &counter{desc: desc, labelPairs: MakeLabelPairs(desc, lvs), now: opts.now}
result.init(result) // Init self-collection.
+ result.createdTs = timestamppb.New(opts.now())
return result
}),
}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go
index deedc2dfb..68ffe3c24 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/desc.go
@@ -52,7 +52,7 @@ type Desc struct {
constLabelPairs []*dto.LabelPair
// variableLabels contains names of labels and normalization function for
// which the metric maintains variable values.
- variableLabels ConstrainedLabels
+ variableLabels *compiledLabels
// id is a hash of the values of the ConstLabels and fqName. This
// must be unique among all registered descriptors and can therefore be
// used as an identifier of the descriptor.
@@ -93,7 +93,7 @@ func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, const
d := &Desc{
fqName: fqName,
help: help,
- variableLabels: variableLabels.constrainedLabels(),
+ variableLabels: variableLabels.compile(),
}
if !model.IsValidMetricName(model.LabelValue(fqName)) {
d.err = fmt.Errorf("%q is not a valid metric name", fqName)
@@ -103,7 +103,7 @@ func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, const
// their sorted label names) plus the fqName (at position 0).
labelValues := make([]string, 1, len(constLabels)+1)
labelValues[0] = fqName
- labelNames := make([]string, 0, len(constLabels)+len(d.variableLabels))
+ labelNames := make([]string, 0, len(constLabels)+len(d.variableLabels.names))
labelNameSet := map[string]struct{}{}
// First add only the const label names and sort them...
for labelName := range constLabels {
@@ -128,13 +128,13 @@ func (v2) NewDesc(fqName, help string, variableLabels ConstrainableLabels, const
// Now add the variable label names, but prefix them with something that
// cannot be in a regular label name. That prevents matching the label
// dimension with a different mix between preset and variable labels.
- for _, label := range d.variableLabels {
- if !checkLabelName(label.Name) {
- d.err = fmt.Errorf("%q is not a valid label name for metric %q", label.Name, fqName)
+ for _, label := range d.variableLabels.names {
+ if !checkLabelName(label) {
+ d.err = fmt.Errorf("%q is not a valid label name for metric %q", label, fqName)
return d
}
- labelNames = append(labelNames, "$"+label.Name)
- labelNameSet[label.Name] = struct{}{}
+ labelNames = append(labelNames, "$"+label)
+ labelNameSet[label] = struct{}{}
}
if len(labelNames) != len(labelNameSet) {
d.err = fmt.Errorf("duplicate label names in constant and variable labels for metric %q", fqName)
@@ -189,11 +189,19 @@ func (d *Desc) String() string {
fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()),
)
}
+ vlStrings := make([]string, 0, len(d.variableLabels.names))
+ for _, vl := range d.variableLabels.names {
+ if fn, ok := d.variableLabels.labelConstraints[vl]; ok && fn != nil {
+ vlStrings = append(vlStrings, fmt.Sprintf("c(%s)", vl))
+ } else {
+ vlStrings = append(vlStrings, vl)
+ }
+ }
return fmt.Sprintf(
- "Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: %v}",
+ "Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: {%s}}",
d.fqName,
d.help,
strings.Join(lpStrings, ","),
- d.variableLabels,
+ strings.Join(vlStrings, ","),
)
}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go
index c41ab37f3..de5a85629 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/expvar_collector.go
@@ -48,7 +48,7 @@ func (e *expvarCollector) Collect(ch chan<- Metric) {
continue
}
var v interface{}
- labels := make([]string, len(desc.variableLabels))
+ labels := make([]string, len(desc.variableLabels.names))
if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil {
ch <- NewInvalidMetric(desc, err)
continue
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
index f1ea6c76f..dd2eac940 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
@@ -62,7 +62,7 @@ type GaugeVecOpts struct {
GaugeOpts
// VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Contraint
+ // of labels. Each label value will be constrained with the optional Constraint
// function, if provided.
VariableLabels ConstrainableLabels
}
@@ -135,7 +135,7 @@ func (g *gauge) Sub(val float64) {
func (g *gauge) Write(out *dto.Metric) error {
val := math.Float64frombits(atomic.LoadUint64(&g.valBits))
- return populateMetric(GaugeValue, val, g.labelPairs, nil, out)
+ return populateMetric(GaugeValue, val, g.labelPairs, nil, out, nil)
}
// GaugeVec is a Collector that bundles a set of Gauges that all share the same
@@ -166,8 +166,8 @@ func (v2) NewGaugeVec(opts GaugeVecOpts) *GaugeVec {
)
return &GaugeVec{
MetricVec: NewMetricVec(desc, func(lvs ...string) Metric {
- if len(lvs) != len(desc.variableLabels) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), lvs))
+ if len(lvs) != len(desc.variableLabels.names) {
+ panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, lvs))
}
result := &gauge{desc: desc, labelPairs: MakeLabelPairs(desc, lvs)}
result.init(result) // Init self-collection.
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
index 8d818afe9..1feba62c6 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
@@ -25,6 +25,7 @@ import (
dto "github.com/prometheus/client_model/go"
"google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/timestamppb"
)
// nativeHistogramBounds for the frac of observed values. Only relevant for
@@ -391,7 +392,7 @@ type HistogramOpts struct {
// zero, it is replaced by default buckets. The default buckets are
// DefBuckets if no buckets for a native histogram (see below) are used,
// otherwise the default is no buckets. (In other words, if you want to
- // use both reguler buckets and buckets for a native histogram, you have
+ // use both regular buckets and buckets for a native histogram, you have
// to define the regular buckets here explicitly.)
Buckets []float64
@@ -413,8 +414,8 @@ type HistogramOpts struct {
// and 2, same as between 2 and 4, and 4 and 8, etc.).
//
// Details about the actually used factor: The factor is calculated as
- // 2^(2^n), where n is an integer number between (and including) -8 and
- // 4. n is chosen so that the resulting factor is the largest that is
+ // 2^(2^-n), where n is an integer number between (and including) -4 and
+ // 8. n is chosen so that the resulting factor is the largest that is
// still smaller or equal to NativeHistogramBucketFactor. Note that the
// smallest possible factor is therefore approx. 1.00271 (i.e. 2^(2^-8)
// ). If NativeHistogramBucketFactor is greater than 1 but smaller than
@@ -428,12 +429,12 @@ type HistogramOpts struct {
// a major version bump.
NativeHistogramBucketFactor float64
// All observations with an absolute value of less or equal
- // NativeHistogramZeroThreshold are accumulated into a “zero”
- // bucket. For best results, this should be close to a bucket
- // boundary. This is usually the case if picking a power of two. If
+ // NativeHistogramZeroThreshold are accumulated into a “zero” bucket.
+ // For best results, this should be close to a bucket boundary. This is
+ // usually the case if picking a power of two. If
// NativeHistogramZeroThreshold is left at zero,
- // DefNativeHistogramZeroThreshold is used as the threshold. To configure
- // a zero bucket with an actual threshold of zero (i.e. only
+ // DefNativeHistogramZeroThreshold is used as the threshold. To
+ // configure a zero bucket with an actual threshold of zero (i.e. only
// observations of precisely zero will go into the zero bucket), set
// NativeHistogramZeroThreshold to the NativeHistogramZeroThresholdZero
// constant (or any negative float value).
@@ -446,26 +447,34 @@ type HistogramOpts struct {
// Histogram are sufficiently wide-spread. In particular, this could be
// used as a DoS attack vector. Where the observed values depend on
// external inputs, it is highly recommended to set a
- // NativeHistogramMaxBucketNumber.) Once the set
+ // NativeHistogramMaxBucketNumber.) Once the set
// NativeHistogramMaxBucketNumber is exceeded, the following strategy is
- // enacted: First, if the last reset (or the creation) of the histogram
- // is at least NativeHistogramMinResetDuration ago, then the whole
- // histogram is reset to its initial state (including regular
- // buckets). If less time has passed, or if
- // NativeHistogramMinResetDuration is zero, no reset is
- // performed. Instead, the zero threshold is increased sufficiently to
- // reduce the number of buckets to or below
- // NativeHistogramMaxBucketNumber, but not to more than
- // NativeHistogramMaxZeroThreshold. Thus, if
- // NativeHistogramMaxZeroThreshold is already at or below the current
- // zero threshold, nothing happens at this step. After that, if the
- // number of buckets still exceeds NativeHistogramMaxBucketNumber, the
- // resolution of the histogram is reduced by doubling the width of the
- // sparse buckets (up to a growth factor between one bucket to the next
- // of 2^(2^4) = 65536, see above).
+ // enacted:
+ // - First, if the last reset (or the creation) of the histogram is at
+ // least NativeHistogramMinResetDuration ago, then the whole
+ // histogram is reset to its initial state (including regular
+ // buckets).
+ // - If less time has passed, or if NativeHistogramMinResetDuration is
+ // zero, no reset is performed. Instead, the zero threshold is
+ // increased sufficiently to reduce the number of buckets to or below
+ // NativeHistogramMaxBucketNumber, but not to more than
+ // NativeHistogramMaxZeroThreshold. Thus, if
+ // NativeHistogramMaxZeroThreshold is already at or below the current
+ // zero threshold, nothing happens at this step.
+ // - After that, if the number of buckets still exceeds
+ // NativeHistogramMaxBucketNumber, the resolution of the histogram is
+ // reduced by doubling the width of the sparse buckets (up to a
+ // growth factor between one bucket to the next of 2^(2^4) = 65536,
+ // see above).
+ // - Any increased zero threshold or reduced resolution is reset back
+ // to their original values once NativeHistogramMinResetDuration has
+ // passed (since the last reset or the creation of the histogram).
NativeHistogramMaxBucketNumber uint32
NativeHistogramMinResetDuration time.Duration
NativeHistogramMaxZeroThreshold float64
+
+ // now is for testing purposes, by default it's time.Now.
+ now func() time.Time
}
// HistogramVecOpts bundles the options to create a HistogramVec metric.
@@ -475,7 +484,7 @@ type HistogramVecOpts struct {
HistogramOpts
// VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Contraint
+ // of labels. Each label value will be constrained with the optional Constraint
// function, if provided.
VariableLabels ConstrainableLabels
}
@@ -499,12 +508,12 @@ func NewHistogram(opts HistogramOpts) Histogram {
}
func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogram {
- if len(desc.variableLabels) != len(labelValues) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), labelValues))
+ if len(desc.variableLabels.names) != len(labelValues) {
+ panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues))
}
- for _, n := range desc.variableLabels {
- if n.Name == bucketLabel {
+ for _, n := range desc.variableLabels.names {
+ if n == bucketLabel {
panic(errBucketLabelNotAllowed)
}
}
@@ -514,6 +523,10 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
}
}
+ if opts.now == nil {
+ opts.now = time.Now
+ }
+
h := &histogram{
desc: desc,
upperBounds: opts.Buckets,
@@ -521,8 +534,8 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
nativeHistogramMaxBuckets: opts.NativeHistogramMaxBucketNumber,
nativeHistogramMaxZeroThreshold: opts.NativeHistogramMaxZeroThreshold,
nativeHistogramMinResetDuration: opts.NativeHistogramMinResetDuration,
- lastResetTime: time.Now(),
- now: time.Now,
+ lastResetTime: opts.now(),
+ now: opts.now,
}
if len(h.upperBounds) == 0 && opts.NativeHistogramBucketFactor <= 1 {
h.upperBounds = DefBuckets
@@ -701,9 +714,11 @@ type histogram struct {
nativeHistogramMaxZeroThreshold float64
nativeHistogramMaxBuckets uint32
nativeHistogramMinResetDuration time.Duration
- lastResetTime time.Time // Protected by mtx.
+ // lastResetTime is protected by mtx. It is also used as created timestamp.
+ lastResetTime time.Time
- now func() time.Time // To mock out time.Now() for testing.
+ // now is for testing purposes, by default it's time.Now.
+ now func() time.Time
}
func (h *histogram) Desc() *Desc {
@@ -742,9 +757,10 @@ func (h *histogram) Write(out *dto.Metric) error {
waitForCooldown(count, coldCounts)
his := &dto.Histogram{
- Bucket: make([]*dto.Bucket, len(h.upperBounds)),
- SampleCount: proto.Uint64(count),
- SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
+ Bucket: make([]*dto.Bucket, len(h.upperBounds)),
+ SampleCount: proto.Uint64(count),
+ SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
+ CreatedTimestamp: timestamppb.New(h.lastResetTime),
}
out.Histogram = his
out.Label = h.labelPairs
@@ -782,6 +798,16 @@ func (h *histogram) Write(out *dto.Metric) error {
his.ZeroCount = proto.Uint64(zeroBucket)
his.NegativeSpan, his.NegativeDelta = makeBuckets(&coldCounts.nativeHistogramBucketsNegative)
his.PositiveSpan, his.PositiveDelta = makeBuckets(&coldCounts.nativeHistogramBucketsPositive)
+
+ // Add a no-op span to a histogram without observations and with
+ // a zero threshold of zero. Otherwise, a native histogram would
+ // look like a classic histogram to scrapers.
+ if *his.ZeroThreshold == 0 && *his.ZeroCount == 0 && len(his.PositiveSpan) == 0 && len(his.NegativeSpan) == 0 {
+ his.PositiveSpan = []*dto.BucketSpan{{
+ Offset: proto.Int32(0),
+ Length: proto.Uint32(0),
+ }}
+ }
}
addAndResetCounts(hotCounts, coldCounts)
return nil
@@ -854,20 +880,23 @@ func (h *histogram) limitBuckets(counts *histogramCounts, value float64, bucket
h.doubleBucketWidth(hotCounts, coldCounts)
}
-// maybeReset resests the whole histogram if at least h.nativeHistogramMinResetDuration
+// maybeReset resets the whole histogram if at least h.nativeHistogramMinResetDuration
// has been passed. It returns true if the histogram has been reset. The caller
// must have locked h.mtx.
-func (h *histogram) maybeReset(hot, cold *histogramCounts, coldIdx uint64, value float64, bucket int) bool {
+func (h *histogram) maybeReset(
+ hot, cold *histogramCounts, coldIdx uint64, value float64, bucket int,
+) bool {
// We are using the possibly mocked h.now() rather than
// time.Since(h.lastResetTime) to enable testing.
- if h.nativeHistogramMinResetDuration == 0 || h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration {
+ if h.nativeHistogramMinResetDuration == 0 ||
+ h.now().Sub(h.lastResetTime) < h.nativeHistogramMinResetDuration {
return false
}
// Completely reset coldCounts.
h.resetCounts(cold)
// Repeat the latest observation to not lose it completely.
cold.observe(value, bucket, true)
- // Make coldCounts the new hot counts while ressetting countAndHotIdx.
+ // Make coldCounts the new hot counts while resetting countAndHotIdx.
n := atomic.SwapUint64(&h.countAndHotIdx, (coldIdx<<63)+1)
count := n & ((1 << 63) - 1)
waitForCooldown(count, hot)
@@ -1176,6 +1205,7 @@ type constHistogram struct {
sum float64
buckets map[float64]uint64
labelPairs []*dto.LabelPair
+ createdTs *timestamppb.Timestamp
}
func (h *constHistogram) Desc() *Desc {
@@ -1183,7 +1213,9 @@ func (h *constHistogram) Desc() *Desc {
}
func (h *constHistogram) Write(out *dto.Metric) error {
- his := &dto.Histogram{}
+ his := &dto.Histogram{
+ CreatedTimestamp: h.createdTs,
+ }
buckets := make([]*dto.Bucket, 0, len(h.buckets))
@@ -1230,7 +1262,7 @@ func NewConstHistogram(
if desc.err != nil {
return nil, desc.err
}
- if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
+ if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
return nil, err
}
return &constHistogram{
@@ -1324,7 +1356,7 @@ func makeBuckets(buckets *sync.Map) ([]*dto.BucketSpan, []int64) {
// Multiple spans with only small gaps in between are probably
// encoded more efficiently as one larger span with a few empty
// buckets. Needs some research to find the sweet spot. For now,
- // we assume that gaps of one ore two buckets should not create
+ // we assume that gaps of one or two buckets should not create
// a new span.
iDelta := int32(i - nextI)
if n == 0 || iDelta > 2 {
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
index fd0750f2c..a595a2036 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go
@@ -14,7 +14,7 @@
// It provides tools to compare sequences of strings and generate textual diffs.
//
// Maintaining `GetUnifiedDiffString` here because original repository
-// (https://github.com/pmezard/go-difflib) is no loger maintained.
+// (https://github.com/pmezard/go-difflib) is no longer maintained.
package internal
import (
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go
index 63ff8683c..b3c4eca2b 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/labels.go
@@ -32,19 +32,15 @@ import (
// create a Desc.
type Labels map[string]string
+// LabelConstraint normalizes label values.
+type LabelConstraint func(string) string
+
// ConstrainedLabels represents a label name and its constrain function
// to normalize label values. This type is commonly used when constructing
// metric vector Collectors.
type ConstrainedLabel struct {
Name string
- Constraint func(string) string
-}
-
-func (cl ConstrainedLabel) Constrain(v string) string {
- if cl.Constraint == nil {
- return v
- }
- return cl.Constraint(v)
+ Constraint LabelConstraint
}
// ConstrainableLabels is an interface that allows creating of labels that can
@@ -58,7 +54,7 @@ func (cl ConstrainedLabel) Constrain(v string) string {
// },
// })
type ConstrainableLabels interface {
- constrainedLabels() ConstrainedLabels
+ compile() *compiledLabels
labelNames() []string
}
@@ -67,8 +63,20 @@ type ConstrainableLabels interface {
// metric vector Collectors.
type ConstrainedLabels []ConstrainedLabel
-func (cls ConstrainedLabels) constrainedLabels() ConstrainedLabels {
- return cls
+func (cls ConstrainedLabels) compile() *compiledLabels {
+ compiled := &compiledLabels{
+ names: make([]string, len(cls)),
+ labelConstraints: map[string]LabelConstraint{},
+ }
+
+ for i, label := range cls {
+ compiled.names[i] = label.Name
+ if label.Constraint != nil {
+ compiled.labelConstraints[label.Name] = label.Constraint
+ }
+ }
+
+ return compiled
}
func (cls ConstrainedLabels) labelNames() []string {
@@ -92,18 +100,36 @@ func (cls ConstrainedLabels) labelNames() []string {
// }
type UnconstrainedLabels []string
-func (uls UnconstrainedLabels) constrainedLabels() ConstrainedLabels {
- constrainedLabels := make([]ConstrainedLabel, len(uls))
- for i, l := range uls {
- constrainedLabels[i] = ConstrainedLabel{Name: l}
+func (uls UnconstrainedLabels) compile() *compiledLabels {
+ return &compiledLabels{
+ names: uls,
}
- return constrainedLabels
}
func (uls UnconstrainedLabels) labelNames() []string {
return uls
}
+type compiledLabels struct {
+ names []string
+ labelConstraints map[string]LabelConstraint
+}
+
+func (cls *compiledLabels) compile() *compiledLabels {
+ return cls
+}
+
+func (cls *compiledLabels) labelNames() []string {
+ return cls.names
+}
+
+func (cls *compiledLabels) constrain(labelName, value string) string {
+ if fn, ok := cls.labelConstraints[labelName]; ok && fn != nil {
+ return fn(value)
+ }
+ return value
+}
+
// reservedLabelPrefix is a prefix which is not legal in user-supplied
// label names.
const reservedLabelPrefix = "__"
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go
index 07bbc9d76..f018e5723 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/metric.go
@@ -92,6 +92,9 @@ type Opts struct {
// machine_role metric). See also
// https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels
ConstLabels Labels
+
+ // now is for testing purposes, by default it's time.Now.
+ now func() time.Time
}
// BuildFQName joins the given three name components by "_". Empty name
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go b/vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go
index fa9011592..58f96599f 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promauto/auto.go
@@ -17,7 +17,7 @@
// constructors register the Collectors with a registry before returning them.
// There are two sets of constructors. The constructors in the first set are
// top-level functions, while the constructors in the other set are methods of
-// the Factory type. The top-level function return Collectors registered with
+// the Factory type. The top-level functions return Collectors registered with
// the global registry (prometheus.DefaultRegisterer), while the methods return
// Collectors registered with the registry the Factory was constructed with. All
// constructors panic if the registration fails.
@@ -85,7 +85,7 @@
// }
//
// A Factory is created with the With(prometheus.Registerer) function, which
-// enables two usage pattern. With(prometheus.Registerer) can be called once per
+// enables two usage patterns. With(prometheus.Registerer) can be called once per
// line:
//
// var (
@@ -153,7 +153,7 @@
// importing a package.
//
// A separate package allows conservative users to entirely ignore it. And
-// whoever wants to use it, will do so explicitly, with an opportunity to read
+// whoever wants to use it will do so explicitly, with an opportunity to read
// this warning.
//
// Enjoy promauto responsibly!
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
index 3793036ad..356edb786 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
@@ -389,15 +389,12 @@ func isLabelCurried(c prometheus.Collector, label string) bool {
return true
}
-// emptyLabels is a one-time allocation for non-partitioned metrics to avoid
-// unnecessary allocations on each request.
-var emptyLabels = prometheus.Labels{}
-
func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels {
+ labels := prometheus.Labels{}
+
if !(code || method) {
- return emptyLabels
+ return labels
}
- labels := prometheus.Labels{}
if code {
labels["code"] = sanitizeCode(status)
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
index 44da9433b..5e2ced25a 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
@@ -548,7 +548,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) {
goroutineBudget--
runtime.Gosched()
}
- // Once both checkedMetricChan and uncheckdMetricChan are closed
+ // Once both checkedMetricChan and uncheckedMetricChan are closed
// and drained, the contraption above will nil out cmc and umc,
// and then we can leave the collect loop here.
if cmc == nil && umc == nil {
@@ -963,9 +963,9 @@ func checkDescConsistency(
// Is the desc consistent with the content of the metric?
lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label))
copy(lpsFromDesc, desc.constLabelPairs)
- for _, l := range desc.variableLabels {
+ for _, l := range desc.variableLabels.names {
lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{
- Name: proto.String(l.Name),
+ Name: proto.String(l),
})
}
if len(lpsFromDesc) != len(dtoMetric.Label) {
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
index dd359264e..146270444 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
@@ -26,6 +26,7 @@ import (
"github.com/beorn7/perks/quantile"
"google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/timestamppb"
)
// quantileLabel is used for the label that defines the quantile in a
@@ -145,6 +146,9 @@ type SummaryOpts struct {
// is the internal buffer size of the underlying package
// "github.com/bmizerany/perks/quantile").
BufCap uint32
+
+ // now is for testing purposes, by default it's time.Now.
+ now func() time.Time
}
// SummaryVecOpts bundles the options to create a SummaryVec metric.
@@ -154,7 +158,7 @@ type SummaryVecOpts struct {
SummaryOpts
// VariableLabels are used to partition the metric vector by the given set
- // of labels. Each label value will be constrained with the optional Contraint
+ // of labels. Each label value will be constrained with the optional Constraint
// function, if provided.
VariableLabels ConstrainableLabels
}
@@ -188,12 +192,12 @@ func NewSummary(opts SummaryOpts) Summary {
}
func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
- if len(desc.variableLabels) != len(labelValues) {
- panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.labelNames(), labelValues))
+ if len(desc.variableLabels.names) != len(labelValues) {
+ panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels.names, labelValues))
}
- for _, n := range desc.variableLabels {
- if n.Name == quantileLabel {
+ for _, n := range desc.variableLabels.names {
+ if n == quantileLabel {
panic(errQuantileLabelNotAllowed)
}
}
@@ -222,6 +226,9 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
opts.BufCap = DefBufCap
}
+ if opts.now == nil {
+ opts.now = time.Now
+ }
if len(opts.Objectives) == 0 {
// Use the lock-free implementation of a Summary without objectives.
s := &noObjectivesSummary{
@@ -230,6 +237,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
counts: [2]*summaryCounts{{}, {}},
}
s.init(s) // Init self-collection.
+ s.createdTs = timestamppb.New(opts.now())
return s
}
@@ -245,7 +253,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
coldBuf: make([]float64, 0, opts.BufCap),
streamDuration: opts.MaxAge / time.Duration(opts.AgeBuckets),
}
- s.headStreamExpTime = time.Now().Add(s.streamDuration)
+ s.headStreamExpTime = opts.now().Add(s.streamDuration)
s.hotBufExpTime = s.headStreamExpTime
for i := uint32(0); i < opts.AgeBuckets; i++ {
@@ -259,6 +267,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
sort.Float64s(s.sortedObjectives)
s.init(s) // Init self-collection.
+ s.createdTs = timestamppb.New(opts.now())
return s
}
@@ -286,6 +295,8 @@ type summary struct {
headStream *quantile.Stream
headStreamIdx int
headStreamExpTime, hotBufExpTime time.Time
+
+ createdTs *timestamppb.Timestamp
}
func (s *summary) Desc() *Desc {
@@ -307,7 +318,9 @@ func (s *summary) Observe(v float64) {
}
func (s *summary) Write(out *dto.Metric) error {
- sum := &dto.Summary{}
+ sum := &dto.Summary{
+ CreatedTimestamp: s.createdTs,
+ }
qs := make([]*dto.Quantile, 0, len(s.objectives))
s.bufMtx.Lock()
@@ -440,6 +453,8 @@ type noObjectivesSummary struct {
counts [2]*summaryCounts
labelPairs []*dto.LabelPair
+
+ createdTs *timestamppb.Timestamp
}
func (s *noObjectivesSummary) Desc() *Desc {
@@ -490,8 +505,9 @@ func (s *noObjectivesSummary) Write(out *dto.Metric) error {
}
sum := &dto.Summary{
- SampleCount: proto.Uint64(count),
- SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
+ SampleCount: proto.Uint64(count),
+ SampleSum: proto.Float64(math.Float64frombits(atomic.LoadUint64(&coldCounts.sumBits))),
+ CreatedTimestamp: s.createdTs,
}
out.Summary = sum
@@ -681,6 +697,7 @@ type constSummary struct {
sum float64
quantiles map[float64]float64
labelPairs []*dto.LabelPair
+ createdTs *timestamppb.Timestamp
}
func (s *constSummary) Desc() *Desc {
@@ -688,7 +705,9 @@ func (s *constSummary) Desc() *Desc {
}
func (s *constSummary) Write(out *dto.Metric) error {
- sum := &dto.Summary{}
+ sum := &dto.Summary{
+ CreatedTimestamp: s.createdTs,
+ }
qs := make([]*dto.Quantile, 0, len(s.quantiles))
sum.SampleCount = proto.Uint64(s.count)
@@ -737,7 +756,7 @@ func NewConstSummary(
if desc.err != nil {
return nil, desc.err
}
- if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
+ if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
return nil, err
}
return &constSummary{
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go
index 5f6bb8001..cc23011fa 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/value.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/value.go
@@ -14,6 +14,7 @@
package prometheus
import (
+ "errors"
"fmt"
"sort"
"time"
@@ -91,7 +92,7 @@ func (v *valueFunc) Desc() *Desc {
}
func (v *valueFunc) Write(out *dto.Metric) error {
- return populateMetric(v.valType, v.function(), v.labelPairs, nil, out)
+ return populateMetric(v.valType, v.function(), v.labelPairs, nil, out, nil)
}
// NewConstMetric returns a metric with one fixed value that cannot be
@@ -105,12 +106,12 @@ func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues
if desc.err != nil {
return nil, desc.err
}
- if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil {
+ if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
return nil, err
}
metric := &dto.Metric{}
- if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric); err != nil {
+ if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, nil); err != nil {
return nil, err
}
@@ -130,6 +131,43 @@ func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelVal
return m
}
+// NewConstMetricWithCreatedTimestamp does the same thing as NewConstMetric, but generates Counters
+// with created timestamp set and returns an error for other metric types.
+func NewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) (Metric, error) {
+ if desc.err != nil {
+ return nil, desc.err
+ }
+ if err := validateLabelValues(labelValues, len(desc.variableLabels.names)); err != nil {
+ return nil, err
+ }
+ switch valueType {
+ case CounterValue:
+ break
+ default:
+ return nil, errors.New("created timestamps are only supported for counters")
+ }
+
+ metric := &dto.Metric{}
+ if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric, timestamppb.New(ct)); err != nil {
+ return nil, err
+ }
+
+ return &constMetric{
+ desc: desc,
+ metric: metric,
+ }, nil
+}
+
+// MustNewConstMetricWithCreatedTimestamp is a version of NewConstMetricWithCreatedTimestamp that panics where
+// NewConstMetricWithCreatedTimestamp would have returned an error.
+func MustNewConstMetricWithCreatedTimestamp(desc *Desc, valueType ValueType, value float64, ct time.Time, labelValues ...string) Metric {
+ m, err := NewConstMetricWithCreatedTimestamp(desc, valueType, value, ct, labelValues...)
+ if err != nil {
+ panic(err)
+ }
+ return m
+}
+
type constMetric struct {
desc *Desc
metric *dto.Metric
@@ -153,11 +191,12 @@ func populateMetric(
labelPairs []*dto.LabelPair,
e *dto.Exemplar,
m *dto.Metric,
+ ct *timestamppb.Timestamp,
) error {
m.Label = labelPairs
switch t {
case CounterValue:
- m.Counter = &dto.Counter{Value: proto.Float64(v), Exemplar: e}
+ m.Counter = &dto.Counter{Value: proto.Float64(v), Exemplar: e, CreatedTimestamp: ct}
case GaugeValue:
m.Gauge = &dto.Gauge{Value: proto.Float64(v)}
case UntypedValue:
@@ -176,19 +215,19 @@ func populateMetric(
// This function is only needed for custom Metric implementations. See MetricVec
// example.
func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
- totalLen := len(desc.variableLabels) + len(desc.constLabelPairs)
+ totalLen := len(desc.variableLabels.names) + len(desc.constLabelPairs)
if totalLen == 0 {
// Super fast path.
return nil
}
- if len(desc.variableLabels) == 0 {
+ if len(desc.variableLabels.names) == 0 {
// Moderately fast path.
return desc.constLabelPairs
}
labelPairs := make([]*dto.LabelPair, 0, totalLen)
- for i, l := range desc.variableLabels {
+ for i, l := range desc.variableLabels.names {
labelPairs = append(labelPairs, &dto.LabelPair{
- Name: proto.String(l.Name),
+ Name: proto.String(l),
Value: proto.String(labelValues[i]),
})
}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go
index f0d0015a0..955cfd59f 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/vec.go
@@ -20,24 +20,6 @@ import (
"github.com/prometheus/common/model"
)
-var labelsPool = &sync.Pool{
- New: func() interface{} {
- return make(Labels)
- },
-}
-
-func getLabelsFromPool() Labels {
- return labelsPool.Get().(Labels)
-}
-
-func putLabelsToPool(labels Labels) {
- for k := range labels {
- delete(labels, k)
- }
-
- labelsPool.Put(labels)
-}
-
// MetricVec is a Collector to bundle metrics of the same name that differ in
// their label values. MetricVec is not used directly but as a building block
// for implementations of vectors of a given metric type, like GaugeVec,
@@ -91,6 +73,7 @@ func NewMetricVec(desc *Desc, newMetric func(lvs ...string) Metric) *MetricVec {
// See also the CounterVec example.
func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
lvs = constrainLabelValues(m.desc, lvs, m.curry)
+
h, err := m.hashLabelValues(lvs)
if err != nil {
return false
@@ -110,8 +93,8 @@ func (m *MetricVec) DeleteLabelValues(lvs ...string) bool {
// This method is used for the same purpose as DeleteLabelValues(...string). See
// there for pros and cons of the two methods.
func (m *MetricVec) Delete(labels Labels) bool {
- labels = constrainLabels(m.desc, labels)
- defer putLabelsToPool(labels)
+ labels, closer := constrainLabels(m.desc, labels)
+ defer closer()
h, err := m.hashLabels(labels)
if err != nil {
@@ -128,8 +111,8 @@ func (m *MetricVec) Delete(labels Labels) bool {
// Note that curried labels will never be matched if deleting from the curried vector.
// To match curried labels with DeletePartialMatch, it must be called on the base vector.
func (m *MetricVec) DeletePartialMatch(labels Labels) int {
- labels = constrainLabels(m.desc, labels)
- defer putLabelsToPool(labels)
+ labels, closer := constrainLabels(m.desc, labels)
+ defer closer()
return m.metricMap.deleteByLabels(labels, m.curry)
}
@@ -169,11 +152,11 @@ func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) {
oldCurry = m.curry
iCurry int
)
- for i, label := range m.desc.variableLabels {
- val, ok := labels[label.Name]
+ for i, labelName := range m.desc.variableLabels.names {
+ val, ok := labels[labelName]
if iCurry < len(oldCurry) && oldCurry[iCurry].index == i {
if ok {
- return nil, fmt.Errorf("label name %q is already curried", label.Name)
+ return nil, fmt.Errorf("label name %q is already curried", labelName)
}
newCurry = append(newCurry, oldCurry[iCurry])
iCurry++
@@ -181,7 +164,10 @@ func (m *MetricVec) CurryWith(labels Labels) (*MetricVec, error) {
if !ok {
continue // Label stays uncurried.
}
- newCurry = append(newCurry, curriedLabelValue{i, label.Constrain(val)})
+ newCurry = append(newCurry, curriedLabelValue{
+ i,
+ m.desc.variableLabels.constrain(labelName, val),
+ })
}
}
if l := len(oldCurry) + len(labels) - len(newCurry); l > 0 {
@@ -250,8 +236,8 @@ func (m *MetricVec) GetMetricWithLabelValues(lvs ...string) (Metric, error) {
// around MetricVec, implementing a vector for a specific Metric implementation,
// for example GaugeVec.
func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
- labels = constrainLabels(m.desc, labels)
- defer putLabelsToPool(labels)
+ labels, closer := constrainLabels(m.desc, labels)
+ defer closer()
h, err := m.hashLabels(labels)
if err != nil {
@@ -262,7 +248,7 @@ func (m *MetricVec) GetMetricWith(labels Labels) (Metric, error) {
}
func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
- if err := validateLabelValues(vals, len(m.desc.variableLabels)-len(m.curry)); err != nil {
+ if err := validateLabelValues(vals, len(m.desc.variableLabels.names)-len(m.curry)); err != nil {
return 0, err
}
@@ -271,7 +257,7 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
curry = m.curry
iVals, iCurry int
)
- for i := 0; i < len(m.desc.variableLabels); i++ {
+ for i := 0; i < len(m.desc.variableLabels.names); i++ {
if iCurry < len(curry) && curry[iCurry].index == i {
h = m.hashAdd(h, curry[iCurry].value)
iCurry++
@@ -285,7 +271,7 @@ func (m *MetricVec) hashLabelValues(vals []string) (uint64, error) {
}
func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
- if err := validateValuesInLabels(labels, len(m.desc.variableLabels)-len(m.curry)); err != nil {
+ if err := validateValuesInLabels(labels, len(m.desc.variableLabels.names)-len(m.curry)); err != nil {
return 0, err
}
@@ -294,17 +280,17 @@ func (m *MetricVec) hashLabels(labels Labels) (uint64, error) {
curry = m.curry
iCurry int
)
- for i, label := range m.desc.variableLabels {
- val, ok := labels[label.Name]
+ for i, labelName := range m.desc.variableLabels.names {
+ val, ok := labels[labelName]
if iCurry < len(curry) && curry[iCurry].index == i {
if ok {
- return 0, fmt.Errorf("label name %q is already curried", label.Name)
+ return 0, fmt.Errorf("label name %q is already curried", labelName)
}
h = m.hashAdd(h, curry[iCurry].value)
iCurry++
} else {
if !ok {
- return 0, fmt.Errorf("label name %q missing in label map", label.Name)
+ return 0, fmt.Errorf("label name %q missing in label map", labelName)
}
h = m.hashAdd(h, val)
}
@@ -482,7 +468,7 @@ func valueMatchesVariableOrCurriedValue(targetValue string, index int, values []
func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool {
for l, v := range labels {
// Check if the target label exists in our metrics and get the index.
- varLabelIndex, validLabel := indexOf(l, desc.variableLabels.labelNames())
+ varLabelIndex, validLabel := indexOf(l, desc.variableLabels.names)
if validLabel {
// Check the value of that label against the target value.
// We don't consider curried values in partial matches.
@@ -626,7 +612,7 @@ func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabe
return false
}
iCurry := 0
- for i, k := range desc.variableLabels {
+ for i, k := range desc.variableLabels.names {
if iCurry < len(curry) && curry[iCurry].index == i {
if values[i] != curry[iCurry].value {
return false
@@ -634,7 +620,7 @@ func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabe
iCurry++
continue
}
- if values[i] != labels[k.Name] {
+ if values[i] != labels[k] {
return false
}
}
@@ -644,13 +630,13 @@ func matchLabels(desc *Desc, values []string, labels Labels, curry []curriedLabe
func extractLabelValues(desc *Desc, labels Labels, curry []curriedLabelValue) []string {
labelValues := make([]string, len(labels)+len(curry))
iCurry := 0
- for i, k := range desc.variableLabels {
+ for i, k := range desc.variableLabels.names {
if iCurry < len(curry) && curry[iCurry].index == i {
labelValues[i] = curry[iCurry].value
iCurry++
continue
}
- labelValues[i] = labels[k.Name]
+ labelValues[i] = labels[k]
}
return labelValues
}
@@ -670,20 +656,37 @@ func inlineLabelValues(lvs []string, curry []curriedLabelValue) []string {
return labelValues
}
-func constrainLabels(desc *Desc, labels Labels) Labels {
- constrainedLabels := getLabelsFromPool()
- for l, v := range labels {
- if i, ok := indexOf(l, desc.variableLabels.labelNames()); ok {
- v = desc.variableLabels[i].Constrain(v)
- }
+var labelsPool = &sync.Pool{
+ New: func() interface{} {
+ return make(Labels)
+ },
+}
- constrainedLabels[l] = v
+func constrainLabels(desc *Desc, labels Labels) (Labels, func()) {
+ if len(desc.variableLabels.labelConstraints) == 0 {
+ // Fast path when there's no constraints
+ return labels, func() {}
}
- return constrainedLabels
+ constrainedLabels := labelsPool.Get().(Labels)
+ for l, v := range labels {
+ constrainedLabels[l] = desc.variableLabels.constrain(l, v)
+ }
+
+ return constrainedLabels, func() {
+ for k := range constrainedLabels {
+ delete(constrainedLabels, k)
+ }
+ labelsPool.Put(constrainedLabels)
+ }
}
func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) []string {
+ if len(desc.variableLabels.labelConstraints) == 0 {
+ // Fast path when there's no constraints
+ return lvs
+ }
+
constrainedValues := make([]string, len(lvs))
var iCurry, iLVs int
for i := 0; i < len(lvs)+len(curry); i++ {
@@ -692,8 +695,11 @@ func constrainLabelValues(desc *Desc, lvs []string, curry []curriedLabelValue) [
continue
}
- if i < len(desc.variableLabels) {
- constrainedValues[iLVs] = desc.variableLabels[i].Constrain(lvs[iLVs])
+ if i < len(desc.variableLabels.names) {
+ constrainedValues[iLVs] = desc.variableLabels.constrain(
+ desc.variableLabels.names[i],
+ lvs[iLVs],
+ )
} else {
constrainedValues[iLVs] = lvs[iLVs]
}