summaryrefslogtreecommitdiff
path: root/vendor/github.com/prometheus/client_golang
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2021-03-17 14:43:10 +0100
committerGiuseppe Scrivano <gscrivan@redhat.com>2021-03-18 20:27:25 +0100
commitec1651fbf11c4d3d1c792e7f46139ebd96f7ffb2 (patch)
tree61606abbce5e8efbf0c1f0c0ff6fe1c785c8a203 /vendor/github.com/prometheus/client_golang
parent77b3a2df645f2548f7bd2da85bbdb17e4de98310 (diff)
downloadpodman-ec1651fbf11c4d3d1c792e7f46139ebd96f7ffb2.tar.gz
podman-ec1651fbf11c4d3d1c792e7f46139ebd96f7ffb2.tar.bz2
podman-ec1651fbf11c4d3d1c792e7f46139ebd96f7ffb2.zip
Bump github.com/containers/storage from 1.25.0 to 1.28.0
Bumps [github.com/containers/storage](https://github.com/containers/storage) from 1.25.0 to 1.28.0. - [Release notes](https://github.com/containers/storage/releases) - [Changelog](https://github.com/containers/storage/blob/master/docs/containers-storage-changes.md) - [Commits](https://github.com/containers/storage/compare/v1.25.0...v1.28.0) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'vendor/github.com/prometheus/client_golang')
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/counter.go50
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/desc.go22
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/doc.go37
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/gauge.go11
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/go_collector.go2
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/histogram.go117
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/metric.go4
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/observer.go12
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go24
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go19
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go82
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/registry.go33
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/summary.go3
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/value.go51
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/vec.go14
-rw-r--r--vendor/github.com/prometheus/client_golang/prometheus/wrap.go14
16 files changed, 363 insertions, 132 deletions
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go
index d463e36d3..0e1b48c03 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/counter.go
@@ -17,6 +17,7 @@ import (
"errors"
"math"
"sync/atomic"
+ "time"
dto "github.com/prometheus/client_model/go"
)
@@ -42,11 +43,27 @@ type Counter interface {
Add(float64)
}
+// ExemplarAdder is implemented by Counters that offer the option of adding a
+// value to the Counter together with an exemplar. Its AddWithExemplar method
+// works like the Add method of the Counter interface but also replaces the
+// currently saved exemplar (if any) with a new one, created from the provided
+// value, the current time as timestamp, and the provided labels. Empty Labels
+// will lead to a valid (label-less) exemplar. But if Labels is nil, the current
+// exemplar is left in place. AddWithExemplar panics if the value is < 0, if any
+// of the provided labels are invalid, or if the provided labels contain more
+// than 64 runes in total.
+type ExemplarAdder interface {
+ AddWithExemplar(value float64, exemplar Labels)
+}
+
// CounterOpts is an alias for Opts. See there for doc comments.
type CounterOpts Opts
// NewCounter creates a new Counter based on the provided CounterOpts.
//
+// The returned implementation also implements ExemplarAdder. It is safe to
+// perform the corresponding type assertion.
+//
// The returned implementation tracks the counter value in two separate
// variables, a float64 and a uint64. The latter is used to track calls of the
// Inc method and calls of the Add method with a value that can be represented
@@ -61,7 +78,7 @@ func NewCounter(opts CounterOpts) Counter {
nil,
opts.ConstLabels,
)
- result := &counter{desc: desc, labelPairs: desc.constLabelPairs}
+ result := &counter{desc: desc, labelPairs: desc.constLabelPairs, now: time.Now}
result.init(result) // Init self-collection.
return result
}
@@ -78,6 +95,9 @@ type counter struct {
desc *Desc
labelPairs []*dto.LabelPair
+ exemplar atomic.Value // Containing nil or a *dto.Exemplar.
+
+ now func() time.Time // To mock out time.Now() for testing.
}
func (c *counter) Desc() *Desc {
@@ -88,6 +108,7 @@ func (c *counter) Add(v float64) {
if v < 0 {
panic(errors.New("counter cannot decrease in value"))
}
+
ival := uint64(v)
if float64(ival) == v {
atomic.AddUint64(&c.valInt, ival)
@@ -103,6 +124,11 @@ func (c *counter) Add(v float64) {
}
}
+func (c *counter) AddWithExemplar(v float64, e Labels) {
+ c.Add(v)
+ c.updateExemplar(v, e)
+}
+
func (c *counter) Inc() {
atomic.AddUint64(&c.valInt, 1)
}
@@ -112,7 +138,23 @@ func (c *counter) Write(out *dto.Metric) error {
ival := atomic.LoadUint64(&c.valInt)
val := fval + float64(ival)
- return populateMetric(CounterValue, val, c.labelPairs, out)
+ var exemplar *dto.Exemplar
+ if e := c.exemplar.Load(); e != nil {
+ exemplar = e.(*dto.Exemplar)
+ }
+
+ return populateMetric(CounterValue, val, c.labelPairs, exemplar, out)
+}
+
+func (c *counter) updateExemplar(v float64, l Labels) {
+ if l == nil {
+ return
+ }
+ e, err := newExemplar(v, c.now(), l)
+ if err != nil {
+ panic(err)
+ }
+ c.exemplar.Store(e)
}
// CounterVec is a Collector that bundles a set of Counters that all share the
@@ -138,7 +180,7 @@ func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
if len(lvs) != len(desc.variableLabels) {
panic(makeInconsistentCardinalityError(desc.fqName, desc.variableLabels, lvs))
}
- result := &counter{desc: desc, labelPairs: makeLabelPairs(desc, lvs)}
+ result := &counter{desc: desc, labelPairs: makeLabelPairs(desc, lvs), now: time.Now}
result.init(result) // Init self-collection.
return result
}),
@@ -267,6 +309,8 @@ type CounterFunc interface {
// provided function must be concurrency-safe. The function should also honor
// the contract for a Counter (values only go up, not down), but compliance will
// not be checked.
+//
+// Check out the ExampleGaugeFunc examples for the similar GaugeFunc.
func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc {
return newValueFunc(NewDesc(
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go
index 1d034f871..2f19f5e1e 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/desc.go
@@ -19,6 +19,8 @@ import (
"sort"
"strings"
+ "github.com/cespare/xxhash/v2"
+ //lint:ignore SA1019 Need to keep deprecated package for compatibility.
"github.com/golang/protobuf/proto"
"github.com/prometheus/common/model"
@@ -126,24 +128,24 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *
return d
}
- vh := hashNew()
+ xxh := xxhash.New()
for _, val := range labelValues {
- vh = hashAdd(vh, val)
- vh = hashAddByte(vh, separatorByte)
+ xxh.WriteString(val)
+ xxh.Write(separatorByteSlice)
}
- d.id = vh
+ d.id = xxh.Sum64()
// Sort labelNames so that order doesn't matter for the hash.
sort.Strings(labelNames)
// Now hash together (in this order) the help string and the sorted
// label names.
- lh := hashNew()
- lh = hashAdd(lh, help)
- lh = hashAddByte(lh, separatorByte)
+ xxh.Reset()
+ xxh.WriteString(help)
+ xxh.Write(separatorByteSlice)
for _, labelName := range labelNames {
- lh = hashAdd(lh, labelName)
- lh = hashAddByte(lh, separatorByte)
+ xxh.WriteString(labelName)
+ xxh.Write(separatorByteSlice)
}
- d.dimHash = lh
+ d.dimHash = xxh.Sum64()
d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))
for n, v := range constLabels {
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/doc.go b/vendor/github.com/prometheus/client_golang/prometheus/doc.go
index 01977de66..98450125d 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/doc.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/doc.go
@@ -84,25 +84,21 @@
// of those four metric types can be found in the Prometheus docs:
// https://prometheus.io/docs/concepts/metric_types/
//
-// A fifth "type" of metric is Untyped. It behaves like a Gauge, but signals the
-// Prometheus server not to assume anything about its type.
-//
-// In addition to the fundamental metric types Gauge, Counter, Summary,
-// Histogram, and Untyped, a very important part of the Prometheus data model is
-// the partitioning of samples along dimensions called labels, which results in
+// In addition to the fundamental metric types Gauge, Counter, Summary, and
+// Histogram, a very important part of the Prometheus data model is the
+// partitioning of samples along dimensions called labels, which results in
// metric vectors. The fundamental types are GaugeVec, CounterVec, SummaryVec,
-// HistogramVec, and UntypedVec.
+// and HistogramVec.
//
// While only the fundamental metric types implement the Metric interface, both
// the metrics and their vector versions implement the Collector interface. A
// Collector manages the collection of a number of Metrics, but for convenience,
-// a Metric can also “collect itself”. Note that Gauge, Counter, Summary,
-// Histogram, and Untyped are interfaces themselves while GaugeVec, CounterVec,
-// SummaryVec, HistogramVec, and UntypedVec are not.
+// a Metric can also “collect itself”. Note that Gauge, Counter, Summary, and
+// Histogram are interfaces themselves while GaugeVec, CounterVec, SummaryVec,
+// and HistogramVec are not.
//
// To create instances of Metrics and their vector versions, you need a suitable
-// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, HistogramOpts, or
-// UntypedOpts.
+// …Opts struct, i.e. GaugeOpts, CounterOpts, SummaryOpts, or HistogramOpts.
//
// Custom Collectors and constant Metrics
//
@@ -118,13 +114,16 @@
// existing numbers into Prometheus Metrics during collection. An own
// implementation of the Collector interface is perfect for that. You can create
// Metric instances “on the fly” using NewConstMetric, NewConstHistogram, and
-// NewConstSummary (and their respective Must… versions). That will happen in
-// the Collect method. The Describe method has to return separate Desc
-// instances, representative of the “throw-away” metrics to be created later.
-// NewDesc comes in handy to create those Desc instances. Alternatively, you
-// could return no Desc at all, which will mark the Collector “unchecked”. No
-// checks are performed at registration time, but metric consistency will still
-// be ensured at scrape time, i.e. any inconsistencies will lead to scrape
+// NewConstSummary (and their respective Must… versions). NewConstMetric is used
+// for all metric types with just a float64 as their value: Counter, Gauge, and
+// a special “type” called Untyped. Use the latter if you are not sure if the
+// mirrored metric is a Counter or a Gauge. Creation of the Metric instance
+// happens in the Collect method. The Describe method has to return separate
+// Desc instances, representative of the “throw-away” metrics to be created
+// later. NewDesc comes in handy to create those Desc instances. Alternatively,
+// you could return no Desc at all, which will mark the Collector “unchecked”.
+// No checks are performed at registration time, but metric consistency will
+// still be ensured at scrape time, i.e. any inconsistencies will lead to scrape
// errors. Thus, with unchecked Collectors, the responsibility to not collect
// metrics that lead to inconsistencies in the total scrape result lies with the
// implementer of the Collector. While this is not a desirable state, it is
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
index 71d406bd9..d67573f76 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/gauge.go
@@ -123,7 +123,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, out)
+ return populateMetric(GaugeValue, val, g.labelPairs, nil, out)
}
// GaugeVec is a Collector that bundles a set of Gauges that all share the same
@@ -273,9 +273,12 @@ type GaugeFunc interface {
// NewGaugeFunc creates a new GaugeFunc based on the provided GaugeOpts. The
// value reported is determined by calling the given function from within the
// Write method. Take into account that metric collection may happen
-// concurrently. If that results in concurrent calls to Write, like in the case
-// where a GaugeFunc is directly registered with Prometheus, the provided
-// function must be concurrency-safe.
+// concurrently. Therefore, it must be safe to call the provided function
+// concurrently.
+//
+// NewGaugeFunc is a good way to create an “info” style metric with a constant
+// value of 1. Example:
+// https://github.com/prometheus/common/blob/8558a5b7db3c84fa38b4766966059a7bd5bfa2ee/version/info.go#L36-L56
func NewGaugeFunc(opts GaugeOpts, function func() float64) GaugeFunc {
return newValueFunc(NewDesc(
BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
index dc9247fed..ea05cf429 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go
@@ -73,7 +73,7 @@ func NewGoCollector() Collector {
nil, nil),
gcDesc: NewDesc(
"go_gc_duration_seconds",
- "A summary of the GC invocation durations.",
+ "A summary of the pause duration of garbage collection cycles.",
nil, nil),
goInfoDesc: NewDesc(
"go_info",
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
index d7ea67bd2..d4ea301a3 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go
@@ -20,7 +20,9 @@ import (
"sort"
"sync"
"sync/atomic"
+ "time"
+ //lint:ignore SA1019 Need to keep deprecated package for compatibility.
"github.com/golang/protobuf/proto"
dto "github.com/prometheus/client_model/go"
@@ -138,7 +140,7 @@ type HistogramOpts struct {
// better covered by target labels set by the scraping Prometheus
// server, or by one specific metric (e.g. a build_info or a
// machine_role metric). See also
- // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels,-not-static-scraped-labels
+ // https://prometheus.io/docs/instrumenting/writing_exporters/#target-labels-not-static-scraped-labels
ConstLabels Labels
// Buckets defines the buckets into which observations are counted. Each
@@ -151,6 +153,10 @@ type HistogramOpts struct {
// NewHistogram creates a new Histogram based on the provided HistogramOpts. It
// panics if the buckets in HistogramOpts are not in strictly increasing order.
+//
+// The returned implementation also implements ExemplarObserver. It is safe to
+// perform the corresponding type assertion. Exemplars are tracked separately
+// for each bucket.
func NewHistogram(opts HistogramOpts) Histogram {
return newHistogram(
NewDesc(
@@ -187,7 +193,8 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
desc: desc,
upperBounds: opts.Buckets,
labelPairs: makeLabelPairs(desc, labelValues),
- counts: [2]*histogramCounts{&histogramCounts{}, &histogramCounts{}},
+ counts: [2]*histogramCounts{{}, {}},
+ now: time.Now,
}
for i, upperBound := range h.upperBounds {
if i < len(h.upperBounds)-1 {
@@ -205,9 +212,10 @@ func newHistogram(desc *Desc, opts HistogramOpts, labelValues ...string) Histogr
}
}
// Finally we know the final length of h.upperBounds and can make buckets
- // for both counts:
+ // for both counts as well as exemplars:
h.counts[0].buckets = make([]uint64, len(h.upperBounds))
h.counts[1].buckets = make([]uint64, len(h.upperBounds))
+ h.exemplars = make([]atomic.Value, len(h.upperBounds)+1)
h.init(h) // Init self-collection.
return h
@@ -254,6 +262,9 @@ type histogram struct {
upperBounds []float64
labelPairs []*dto.LabelPair
+ exemplars []atomic.Value // One more than buckets (to include +Inf), each a *dto.Exemplar.
+
+ now func() time.Time // To mock out time.Now() for testing.
}
func (h *histogram) Desc() *Desc {
@@ -261,36 +272,13 @@ func (h *histogram) Desc() *Desc {
}
func (h *histogram) Observe(v float64) {
- // TODO(beorn7): For small numbers of buckets (<30), a linear search is
- // slightly faster than the binary search. If we really care, we could
- // switch from one search strategy to the other depending on the number
- // of buckets.
- //
- // Microbenchmarks (BenchmarkHistogramNoLabels):
- // 11 buckets: 38.3 ns/op linear - binary 48.7 ns/op
- // 100 buckets: 78.1 ns/op linear - binary 54.9 ns/op
- // 300 buckets: 154 ns/op linear - binary 61.6 ns/op
- i := sort.SearchFloat64s(h.upperBounds, v)
-
- // We increment h.countAndHotIdx so that the counter in the lower
- // 63 bits gets incremented. At the same time, we get the new value
- // back, which we can use to find the currently-hot counts.
- n := atomic.AddUint64(&h.countAndHotIdx, 1)
- hotCounts := h.counts[n>>63]
+ h.observe(v, h.findBucket(v))
+}
- if i < len(h.upperBounds) {
- atomic.AddUint64(&hotCounts.buckets[i], 1)
- }
- for {
- oldBits := atomic.LoadUint64(&hotCounts.sumBits)
- newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
- if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
- break
- }
- }
- // Increment count last as we take it as a signal that the observation
- // is complete.
- atomic.AddUint64(&hotCounts.count, 1)
+func (h *histogram) ObserveWithExemplar(v float64, e Labels) {
+ i := h.findBucket(v)
+ h.observe(v, i)
+ h.updateExemplar(v, i, e)
}
func (h *histogram) Write(out *dto.Metric) error {
@@ -329,6 +317,18 @@ func (h *histogram) Write(out *dto.Metric) error {
CumulativeCount: proto.Uint64(cumCount),
UpperBound: proto.Float64(upperBound),
}
+ if e := h.exemplars[i].Load(); e != nil {
+ his.Bucket[i].Exemplar = e.(*dto.Exemplar)
+ }
+ }
+ // If there is an exemplar for the +Inf bucket, we have to add that bucket explicitly.
+ if e := h.exemplars[len(h.upperBounds)].Load(); e != nil {
+ b := &dto.Bucket{
+ CumulativeCount: proto.Uint64(count),
+ UpperBound: proto.Float64(math.Inf(1)),
+ Exemplar: e.(*dto.Exemplar),
+ }
+ his.Bucket = append(his.Bucket, b)
}
out.Histogram = his
@@ -352,6 +352,57 @@ func (h *histogram) Write(out *dto.Metric) error {
return nil
}
+// findBucket returns the index of the bucket for the provided value, or
+// len(h.upperBounds) for the +Inf bucket.
+func (h *histogram) findBucket(v float64) int {
+ // TODO(beorn7): For small numbers of buckets (<30), a linear search is
+ // slightly faster than the binary search. If we really care, we could
+ // switch from one search strategy to the other depending on the number
+ // of buckets.
+ //
+ // Microbenchmarks (BenchmarkHistogramNoLabels):
+ // 11 buckets: 38.3 ns/op linear - binary 48.7 ns/op
+ // 100 buckets: 78.1 ns/op linear - binary 54.9 ns/op
+ // 300 buckets: 154 ns/op linear - binary 61.6 ns/op
+ return sort.SearchFloat64s(h.upperBounds, v)
+}
+
+// observe is the implementation for Observe without the findBucket part.
+func (h *histogram) observe(v float64, bucket int) {
+ // We increment h.countAndHotIdx so that the counter in the lower
+ // 63 bits gets incremented. At the same time, we get the new value
+ // back, which we can use to find the currently-hot counts.
+ n := atomic.AddUint64(&h.countAndHotIdx, 1)
+ hotCounts := h.counts[n>>63]
+
+ if bucket < len(h.upperBounds) {
+ atomic.AddUint64(&hotCounts.buckets[bucket], 1)
+ }
+ for {
+ oldBits := atomic.LoadUint64(&hotCounts.sumBits)
+ newBits := math.Float64bits(math.Float64frombits(oldBits) + v)
+ if atomic.CompareAndSwapUint64(&hotCounts.sumBits, oldBits, newBits) {
+ break
+ }
+ }
+ // Increment count last as we take it as a signal that the observation
+ // is complete.
+ atomic.AddUint64(&hotCounts.count, 1)
+}
+
+// updateExemplar replaces the exemplar for the provided bucket. With empty
+// labels, it's a no-op. It panics if any of the labels is invalid.
+func (h *histogram) updateExemplar(v float64, bucket int, l Labels) {
+ if l == nil {
+ return
+ }
+ e, err := newExemplar(v, h.now(), l)
+ if err != nil {
+ panic(err)
+ }
+ h.exemplars[bucket].Store(e)
+}
+
// HistogramVec is a Collector that bundles a set of Histograms that all share the
// same Desc, but have different values for their variable labels. This is used
// if you want to count the same thing partitioned by various dimensions
@@ -556,7 +607,7 @@ func NewConstHistogram(
}
// MustNewConstHistogram is a version of NewConstHistogram that panics where
-// NewConstMetric would have returned an error.
+// NewConstHistogram would have returned an error.
func MustNewConstHistogram(
desc *Desc,
count uint64,
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go
index 55e6d86d5..35bd8bde3 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/metric.go
@@ -17,12 +17,14 @@ import (
"strings"
"time"
+ //lint:ignore SA1019 Need to keep deprecated package for compatibility.
"github.com/golang/protobuf/proto"
+ "github.com/prometheus/common/model"
dto "github.com/prometheus/client_model/go"
)
-const separatorByte byte = 255
+var separatorByteSlice = []byte{model.SeparatorByte} // For convenient use with xxhash.
// A Metric models a single sample value with its meta data being exported to
// Prometheus. Implementations of Metric in this package are Gauge, Counter,
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/observer.go b/vendor/github.com/prometheus/client_golang/prometheus/observer.go
index 5806cd09e..44128016f 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/observer.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/observer.go
@@ -50,3 +50,15 @@ type ObserverVec interface {
Collector
}
+
+// ExemplarObserver is implemented by Observers that offer the option of
+// observing a value together with an exemplar. Its ObserveWithExemplar method
+// works like the Observe method of an Observer but also replaces the currently
+// saved exemplar (if any) with a new one, created from the provided value, the
+// current time as timestamp, and the provided Labels. Empty Labels will lead to
+// a valid (label-less) exemplar. But if Labels is nil, the current exemplar is
+// left in place. ObserveWithExemplar panics if any of the provided labels are
+// invalid or if the provided labels contain more than 64 runes in total.
+type ExemplarObserver interface {
+ ObserveWithExemplar(value float64, exemplar Labels)
+}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
index e0b935d1f..f973398df 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_windows.go
@@ -33,18 +33,22 @@ var (
)
type processMemoryCounters struct {
- // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-_process_memory_counters_ex
+ // System interface description
+ // https://docs.microsoft.com/en-us/windows/desktop/api/psapi/ns-psapi-process_memory_counters_ex
+
+ // Refer to the Golang internal implementation
+ // https://golang.org/src/internal/syscall/windows/psapi_windows.go
_ uint32
PageFaultCount uint32
- PeakWorkingSetSize uint64
- WorkingSetSize uint64
- QuotaPeakPagedPoolUsage uint64
- QuotaPagedPoolUsage uint64
- QuotaPeakNonPagedPoolUsage uint64
- QuotaNonPagedPoolUsage uint64
- PagefileUsage uint64
- PeakPagefileUsage uint64
- PrivateUsage uint64
+ PeakWorkingSetSize uintptr
+ WorkingSetSize uintptr
+ QuotaPeakPagedPoolUsage uintptr
+ QuotaPagedPoolUsage uintptr
+ QuotaPeakNonPagedPoolUsage uintptr
+ QuotaNonPagedPoolUsage uintptr
+ PagefileUsage uintptr
+ PeakPagefileUsage uintptr
+ PrivateUsage uintptr
}
func getProcessMemoryInfo(handle windows.Handle) (processMemoryCounters, error) {
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
index fa535684f..5070e72e2 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go
@@ -53,15 +53,21 @@ func (r *responseWriterDelegator) Written() int64 {
}
func (r *responseWriterDelegator) WriteHeader(code int) {
+ if r.observeWriteHeader != nil && !r.wroteHeader {
+ // Only call observeWriteHeader for the 1st time. It's a bug if
+ // WriteHeader is called more than once, but we want to protect
+ // against it here. Note that we still delegate the WriteHeader
+ // to the original ResponseWriter to not mask the bug from it.
+ r.observeWriteHeader(code)
+ }
r.status = code
r.wroteHeader = true
r.ResponseWriter.WriteHeader(code)
- if r.observeWriteHeader != nil {
- r.observeWriteHeader(code)
- }
}
func (r *responseWriterDelegator) Write(b []byte) (int, error) {
+ // If applicable, call WriteHeader here so that observeWriteHeader is
+ // handled appropriately.
if !r.wroteHeader {
r.WriteHeader(http.StatusOK)
}
@@ -82,12 +88,19 @@ func (d closeNotifierDelegator) CloseNotify() <-chan bool {
return d.ResponseWriter.(http.CloseNotifier).CloseNotify()
}
func (d flusherDelegator) Flush() {
+ // If applicable, call WriteHeader here so that observeWriteHeader is
+ // handled appropriately.
+ if !d.wroteHeader {
+ d.WriteHeader(http.StatusOK)
+ }
d.ResponseWriter.(http.Flusher).Flush()
}
func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return d.ResponseWriter.(http.Hijacker).Hijack()
}
func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) {
+ // If applicable, call WriteHeader here so that observeWriteHeader is
+ // handled appropriately.
if !d.wroteHeader {
d.WriteHeader(http.StatusOK)
}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
index cea5a90fd..5e1c4546c 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go
@@ -144,7 +144,12 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
}
}
- contentType := expfmt.Negotiate(req.Header)
+ var contentType expfmt.Format
+ if opts.EnableOpenMetrics {
+ contentType = expfmt.NegotiateIncludingOpenMetrics(req.Header)
+ } else {
+ contentType = expfmt.Negotiate(req.Header)
+ }
header := rsp.Header()
header.Set(contentTypeHeader, string(contentType))
@@ -162,28 +167,40 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler {
enc := expfmt.NewEncoder(w, contentType)
- var lastErr error
- for _, mf := range mfs {
- if err := enc.Encode(mf); err != nil {
- lastErr = err
- if opts.ErrorLog != nil {
- opts.ErrorLog.Println("error encoding and sending metric family:", err)
- }
- errCnt.WithLabelValues("encoding").Inc()
- switch opts.ErrorHandling {
- case PanicOnError:
- panic(err)
- case ContinueOnError:
- // Handled later.
- case HTTPErrorOnError:
- httpError(rsp, err)
- return
- }
+ // handleError handles the error according to opts.ErrorHandling
+ // and returns true if we have to abort after the handling.
+ handleError := func(err error) bool {
+ if err == nil {
+ return false
+ }
+ if opts.ErrorLog != nil {
+ opts.ErrorLog.Println("error encoding and sending metric family:", err)
+ }
+ errCnt.WithLabelValues("encoding").Inc()
+ switch opts.ErrorHandling {
+ case PanicOnError:
+ panic(err)
+ case HTTPErrorOnError:
+ // We cannot really send an HTTP error at this
+ // point because we most likely have written
+ // something to rsp already. But at least we can
+ // stop sending.
+ return true
}
+ // Do nothing in all other cases, including ContinueOnError.
+ return false
}
- if lastErr != nil {
- httpError(rsp, lastErr)
+ for _, mf := range mfs {
+ if handleError(enc.Encode(mf)) {
+ return
+ }
+ }
+ if closer, ok := enc.(expfmt.Closer); ok {
+ // This in particular takes care of the final "# EOF\n" line for OpenMetrics.
+ if handleError(closer.Close()) {
+ return
+ }
}
})
@@ -255,7 +272,12 @@ type HandlerErrorHandling int
// errors are encountered.
const (
// Serve an HTTP status code 500 upon the first error
- // encountered. Report the error message in the body.
+ // encountered. Report the error message in the body. Note that HTTP
+ // errors cannot be served anymore once the beginning of a regular
+ // payload has been sent. Thus, in the (unlikely) case that encoding the
+ // payload into the negotiated wire format fails, serving the response
+ // will simply be aborted. Set an ErrorLog in HandlerOpts to detect
+ // those errors.
HTTPErrorOnError HandlerErrorHandling = iota
// Ignore errors and try to serve as many metrics as possible. However,
// if no metrics can be served, serve an HTTP status code 500 and the
@@ -318,6 +340,16 @@ type HandlerOpts struct {
// away). Until the implementation is improved, it is recommended to
// implement a separate timeout in potentially slow Collectors.
Timeout time.Duration
+ // If true, the experimental OpenMetrics encoding is added to the
+ // possible options during content negotiation. Note that Prometheus
+ // 2.5.0+ will negotiate OpenMetrics as first priority. OpenMetrics is
+ // the only way to transmit exemplars. However, the move to OpenMetrics
+ // is not completely transparent. Most notably, the values of "quantile"
+ // labels of Summaries and "le" labels of Histograms are formatted with
+ // a trailing ".0" if they would otherwise look like integer numbers
+ // (which changes the identity of the resulting series on the Prometheus
+ // server).
+ EnableOpenMetrics bool
}
// gzipAccepted returns whether the client will accept gzip-encoded content.
@@ -334,11 +366,9 @@ func gzipAccepted(header http.Header) bool {
}
// httpError removes any content-encoding header and then calls http.Error with
-// the provided error and http.StatusInternalServerErrer. Error contents is
-// supposed to be uncompressed plain text. However, same as with a plain
-// http.Error, any header settings will be void if the header has already been
-// sent. The error message will still be written to the writer, but it will
-// probably be of limited use.
+// the provided error and http.StatusInternalServerError. Error contents is
+// supposed to be uncompressed plain text. Same as with a plain http.Error, this
+// must not be called if the header or any payload has already been sent.
func httpError(rsp http.ResponseWriter, err error) {
rsp.Header().Del(contentEncodingHeader)
http.Error(
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
index 6c32516aa..ba94405af 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go
@@ -25,6 +25,8 @@ import (
"sync"
"unicode/utf8"
+ "github.com/cespare/xxhash/v2"
+ //lint:ignore SA1019 Need to keep deprecated package for compatibility.
"github.com/golang/protobuf/proto"
"github.com/prometheus/common/expfmt"
@@ -74,7 +76,7 @@ func NewRegistry() *Registry {
// NewPedanticRegistry returns a registry that checks during collection if each
// collected Metric is consistent with its reported Desc, and if the Desc has
// actually been registered with the registry. Unchecked Collectors (those whose
-// Describe methed does not yield any descriptors) are excluded from the check.
+// Describe method does not yield any descriptors) are excluded from the check.
//
// Usually, a Registry will be happy as long as the union of all collected
// Metrics is consistent and valid even if some metrics are not consistent with
@@ -266,7 +268,7 @@ func (r *Registry) Register(c Collector) error {
descChan = make(chan *Desc, capDescChan)
newDescIDs = map[uint64]struct{}{}
newDimHashesByName = map[string]uint64{}
- collectorID uint64 // Just a sum of all desc IDs.
+ collectorID uint64 // All desc IDs XOR'd together.
duplicateDescErr error
)
go func() {
@@ -293,12 +295,12 @@ func (r *Registry) Register(c Collector) error {
if _, exists := r.descIDs[desc.id]; exists {
duplicateDescErr = fmt.Errorf("descriptor %s already exists with the same fully-qualified name and const label values", desc)
}
- // If it is not a duplicate desc in this collector, add it to
+ // If it is not a duplicate desc in this collector, XOR it to
// the collectorID. (We allow duplicate descs within the same
// collector, but their existence must be a no-op.)
if _, exists := newDescIDs[desc.id]; !exists {
newDescIDs[desc.id] = struct{}{}
- collectorID += desc.id
+ collectorID ^= desc.id
}
// Are all the label names and the help string consistent with
@@ -360,7 +362,7 @@ func (r *Registry) Unregister(c Collector) bool {
var (
descChan = make(chan *Desc, capDescChan)
descIDs = map[uint64]struct{}{}
- collectorID uint64 // Just a sum of the desc IDs.
+ collectorID uint64 // All desc IDs XOR'd together.
)
go func() {
c.Describe(descChan)
@@ -368,7 +370,7 @@ func (r *Registry) Unregister(c Collector) bool {
}()
for desc := range descChan {
if _, exists := descIDs[desc.id]; !exists {
- collectorID += desc.id
+ collectorID ^= desc.id
descIDs[desc.id] = struct{}{}
}
}
@@ -875,9 +877,9 @@ func checkMetricConsistency(
}
// Is the metric unique (i.e. no other metric with the same name and the same labels)?
- h := hashNew()
- h = hashAdd(h, name)
- h = hashAddByte(h, separatorByte)
+ h := xxhash.New()
+ h.WriteString(name)
+ h.Write(separatorByteSlice)
// Make sure label pairs are sorted. We depend on it for the consistency
// check.
if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) {
@@ -888,18 +890,19 @@ func checkMetricConsistency(
dtoMetric.Label = copiedLabels
}
for _, lp := range dtoMetric.Label {
- h = hashAdd(h, lp.GetName())
- h = hashAddByte(h, separatorByte)
- h = hashAdd(h, lp.GetValue())
- h = hashAddByte(h, separatorByte)
+ h.WriteString(lp.GetName())
+ h.Write(separatorByteSlice)
+ h.WriteString(lp.GetValue())
+ h.Write(separatorByteSlice)
}
- if _, exists := metricHashes[h]; exists {
+ hSum := h.Sum64()
+ if _, exists := metricHashes[hSum]; exists {
return fmt.Errorf(
"collected metric %q { %s} was collected before with the same name and label values",
name, dtoMetric,
)
}
- metricHashes[h] = struct{}{}
+ metricHashes[hSum] = struct{}{}
return nil
}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/summary.go b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
index c970fdee0..f3c1440d1 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/summary.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/summary.go
@@ -23,6 +23,7 @@ import (
"time"
"github.com/beorn7/perks/quantile"
+ //lint:ignore SA1019 Need to keep deprecated package for compatibility.
"github.com/golang/protobuf/proto"
dto "github.com/prometheus/client_model/go"
@@ -208,7 +209,7 @@ func newSummary(desc *Desc, opts SummaryOpts, labelValues ...string) Summary {
s := &noObjectivesSummary{
desc: desc,
labelPairs: makeLabelPairs(desc, labelValues),
- counts: [2]*summaryCounts{&summaryCounts{}, &summaryCounts{}},
+ counts: [2]*summaryCounts{{}, {}},
}
s.init(s) // Init self-collection.
return s
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go
index eb248f108..6206928cc 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/value.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/value.go
@@ -16,8 +16,12 @@ package prometheus
import (
"fmt"
"sort"
+ "time"
+ "unicode/utf8"
+ //lint:ignore SA1019 Need to keep deprecated package for compatibility.
"github.com/golang/protobuf/proto"
+ "github.com/golang/protobuf/ptypes"
dto "github.com/prometheus/client_model/go"
)
@@ -25,7 +29,8 @@ import (
// ValueType is an enumeration of metric types that represent a simple value.
type ValueType int
-// Possible values for the ValueType enum.
+// Possible values for the ValueType enum. Use UntypedValue to mark a metric
+// with an unknown type.
const (
_ ValueType = iota
CounterValue
@@ -69,7 +74,7 @@ func (v *valueFunc) Desc() *Desc {
}
func (v *valueFunc) Write(out *dto.Metric) error {
- return populateMetric(v.valType, v.function(), v.labelPairs, out)
+ return populateMetric(v.valType, v.function(), v.labelPairs, nil, out)
}
// NewConstMetric returns a metric with one fixed value that cannot be
@@ -116,19 +121,20 @@ func (m *constMetric) Desc() *Desc {
}
func (m *constMetric) Write(out *dto.Metric) error {
- return populateMetric(m.valType, m.val, m.labelPairs, out)
+ return populateMetric(m.valType, m.val, m.labelPairs, nil, out)
}
func populateMetric(
t ValueType,
v float64,
labelPairs []*dto.LabelPair,
+ e *dto.Exemplar,
m *dto.Metric,
) error {
m.Label = labelPairs
switch t {
case CounterValue:
- m.Counter = &dto.Counter{Value: proto.Float64(v)}
+ m.Counter = &dto.Counter{Value: proto.Float64(v), Exemplar: e}
case GaugeValue:
m.Gauge = &dto.Gauge{Value: proto.Float64(v)}
case UntypedValue:
@@ -160,3 +166,40 @@ func makeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair {
sort.Sort(labelPairSorter(labelPairs))
return labelPairs
}
+
+// ExemplarMaxRunes is the max total number of runes allowed in exemplar labels.
+const ExemplarMaxRunes = 64
+
+// newExemplar creates a new dto.Exemplar from the provided values. An error is
+// returned if any of the label names or values are invalid or if the total
+// number of runes in the label names and values exceeds ExemplarMaxRunes.
+func newExemplar(value float64, ts time.Time, l Labels) (*dto.Exemplar, error) {
+ e := &dto.Exemplar{}
+ e.Value = proto.Float64(value)
+ tsProto, err := ptypes.TimestampProto(ts)
+ if err != nil {
+ return nil, err
+ }
+ e.Timestamp = tsProto
+ labelPairs := make([]*dto.LabelPair, 0, len(l))
+ var runes int
+ for name, value := range l {
+ if !checkLabelName(name) {
+ return nil, fmt.Errorf("exemplar label name %q is invalid", name)
+ }
+ runes += utf8.RuneCountInString(name)
+ if !utf8.ValidString(value) {
+ return nil, fmt.Errorf("exemplar label value %q is not valid UTF-8", value)
+ }
+ runes += utf8.RuneCountInString(value)
+ labelPairs = append(labelPairs, &dto.LabelPair{
+ Name: proto.String(name),
+ Value: proto.String(value),
+ })
+ }
+ if runes > ExemplarMaxRunes {
+ return nil, fmt.Errorf("exemplar labels have %d runes, exceeding the limit of %d", runes, ExemplarMaxRunes)
+ }
+ e.Label = labelPairs
+ return e, nil
+}
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go
index 14ed9e856..d53848dc4 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/vec.go
@@ -24,7 +24,7 @@ import (
// their label values. metricVec is not used directly (and therefore
// unexported). It is used as a building block for implementations of vectors of
// a given metric type, like GaugeVec, CounterVec, SummaryVec, and HistogramVec.
-// It also handles label currying. It uses basicMetricVec internally.
+// It also handles label currying.
type metricVec struct {
*metricMap
@@ -91,6 +91,18 @@ func (m *metricVec) Delete(labels Labels) bool {
return m.metricMap.deleteByHashWithLabels(h, labels, m.curry)
}
+// Without explicit forwarding of Describe, Collect, Reset, those methods won't
+// show up in GoDoc.
+
+// Describe implements Collector.
+func (m *metricVec) Describe(ch chan<- *Desc) { m.metricMap.Describe(ch) }
+
+// Collect implements Collector.
+func (m *metricVec) Collect(ch chan<- Metric) { m.metricMap.Collect(ch) }
+
+// Reset deletes all metrics in this vector.
+func (m *metricVec) Reset() { m.metricMap.Reset() }
+
func (m *metricVec) curryWith(labels Labels) (*metricVec, error) {
var (
newCurry []curriedLabelValue
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
index e303eef6d..438aa5e92 100644
--- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go
@@ -17,6 +17,7 @@ import (
"fmt"
"sort"
+ //lint:ignore SA1019 Need to keep deprecated package for compatibility.
"github.com/golang/protobuf/proto"
dto "github.com/prometheus/client_model/go"
@@ -27,7 +28,8 @@ import (
// registered with the wrapped Registerer in a modified way. The modified
// Collector adds the provided Labels to all Metrics it collects (as
// ConstLabels). The Metrics collected by the unmodified Collector must not
-// duplicate any of those labels.
+// duplicate any of those labels. Wrapping a nil value is valid, resulting
+// in a no-op Registerer.
//
// WrapRegistererWith provides a way to add fixed labels to a subset of
// Collectors. It should not be used to add fixed labels to all metrics exposed.
@@ -50,6 +52,7 @@ func WrapRegistererWith(labels Labels, reg Registerer) Registerer {
// Registerer. Collectors registered with the returned Registerer will be
// registered with the wrapped Registerer in a modified way. The modified
// Collector adds the provided prefix to the name of all Metrics it collects.
+// Wrapping a nil value is valid, resulting in a no-op Registerer.
//
// WrapRegistererWithPrefix is useful to have one place to prefix all metrics of
// a sub-system. To make this work, register metrics of the sub-system with the
@@ -80,6 +83,9 @@ type wrappingRegisterer struct {
}
func (r *wrappingRegisterer) Register(c Collector) error {
+ if r.wrappedRegisterer == nil {
+ return nil
+ }
return r.wrappedRegisterer.Register(&wrappingCollector{
wrappedCollector: c,
prefix: r.prefix,
@@ -88,6 +94,9 @@ func (r *wrappingRegisterer) Register(c Collector) error {
}
func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
+ if r.wrappedRegisterer == nil {
+ return
+ }
for _, c := range cs {
if err := r.Register(c); err != nil {
panic(err)
@@ -96,6 +105,9 @@ func (r *wrappingRegisterer) MustRegister(cs ...Collector) {
}
func (r *wrappingRegisterer) Unregister(c Collector) bool {
+ if r.wrappedRegisterer == nil {
+ return false
+ }
return r.wrappedRegisterer.Unregister(&wrappingCollector{
wrappedCollector: c,
prefix: r.prefix,