Merge branch 'main' into sparsehistogram

This commit is contained in:
beorn7 2022-10-19 18:09:21 +02:00
commit 111fae11e1
6 changed files with 21 additions and 15 deletions

View File

@ -22,6 +22,7 @@ import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"regexp"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/collectors"
@ -39,7 +40,7 @@ func main() {
// Add Go module build info. // Add Go module build info.
reg.MustRegister(collectors.NewBuildInfoCollector()) reg.MustRegister(collectors.NewBuildInfoCollector())
reg.MustRegister(collectors.NewGoCollector( reg.MustRegister(collectors.NewGoCollector(
collectors.WithGoCollections(collectors.GoRuntimeMemStatsCollection | collectors.GoRuntimeMetricsCollection), collectors.WithGoCollectorRuntimeMetrics(collectors.GoRuntimeMetricsRule{Matcher: regexp.MustCompile("/.*")}),
)) ))
// Expose the registered metrics via HTTP. // Expose the registered metrics via HTTP.

View File

@ -140,12 +140,13 @@ func (c *counter) get() float64 {
} }
func (c *counter) Write(out *dto.Metric) error { func (c *counter) Write(out *dto.Metric) error {
val := c.get() // Read the Exemplar first and the value second. This is to avoid a race condition
// where users see an exemplar for a not-yet-existing observation.
var exemplar *dto.Exemplar var exemplar *dto.Exemplar
if e := c.exemplar.Load(); e != nil { if e := c.exemplar.Load(); e != nil {
exemplar = e.(*dto.Exemplar) exemplar = e.(*dto.Exemplar)
} }
val := c.get()
return populateMetric(CounterValue, val, c.labelPairs, exemplar, out) return populateMetric(CounterValue, val, c.labelPairs, exemplar, out)
} }

View File

@ -1170,7 +1170,7 @@ func (h *constHistogram) Write(out *dto.Metric) error {
// to send it to Prometheus in the Collect method. // to send it to Prometheus in the Collect method.
// //
// buckets is a map of upper bounds to cumulative counts, excluding the +Inf // buckets is a map of upper bounds to cumulative counts, excluding the +Inf
// bucket. // bucket. The +Inf bucket is implicit, and its value is equal to the provided count.
// //
// NewConstHistogram returns an error if the length of labelValues is not // NewConstHistogram returns an error if the length of labelValues is not
// consistent with the variable labels in Desc or if Desc is invalid. // consistent with the variable labels in Desc or if Desc is invalid.

View File

@ -187,7 +187,7 @@ func (m *withExemplarsMetric) Write(pb *dto.Metric) error {
} else { } else {
// The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365. // The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365.
b := &dto.Bucket{ b := &dto.Bucket{
CumulativeCount: proto.Uint64(pb.Histogram.Bucket[len(pb.Histogram.GetBucket())-1].GetCumulativeCount()), CumulativeCount: proto.Uint64(pb.Histogram.GetSampleCount()),
UpperBound: proto.Float64(math.Inf(1)), UpperBound: proto.Float64(math.Inf(1)),
Exemplar: e, Exemplar: e,
} }

View File

@ -79,10 +79,14 @@ func TestWithExemplarsMetric(t *testing.T) {
} }
} }
infBucket := metric.GetHistogram().Bucket[len(metric.GetHistogram().Bucket)-1].GetUpperBound() infBucket := metric.GetHistogram().Bucket[len(metric.GetHistogram().Bucket)-1]
if infBucket != math.Inf(1) { if want, got := math.Inf(1), infBucket.GetUpperBound(); want != got {
t.Errorf("want %v, got %v", math.Inf(1), infBucket) t.Errorf("want %v, got %v", want, got)
}
if want, got := uint64(4711), infBucket.GetCumulativeCount(); want != got {
t.Errorf("want %v, got %v", want, got)
} }
}) })
} }

View File

@ -14,13 +14,13 @@
// Package promauto provides alternative constructors for the fundamental // Package promauto provides alternative constructors for the fundamental
// Prometheus metric types and their …Vec and …Func variants. The difference to // Prometheus metric types and their …Vec and …Func variants. The difference to
// their counterparts in the prometheus package is that the promauto // their counterparts in the prometheus package is that the promauto
// constructors return Collectors that are already registered with a // constructors register the Collectors with a registry before returning them.
// registry. There are two sets of constructors. The constructors in the first // There are two sets of constructors. The constructors in the first set are
// set are top-level functions, while the constructors in the other set are // top-level functions, while the constructors in the other set are methods of
// methods of the Factory type. The top-level function return Collectors // the Factory type. The top-level function return Collectors registered with
// registered with the global registry (prometheus.DefaultRegisterer), while the // the global registry (prometheus.DefaultRegisterer), while the methods return
// methods return Collectors registered with the registry the Factory was // Collectors registered with the registry the Factory was constructed with. All
// constructed with. All constructors panic if the registration fails. // constructors panic if the registration fails.
// //
// The following example is a complete program to create a histogram of normally // The following example is a complete program to create a histogram of normally
// distributed random numbers from the math/rand package: // distributed random numbers from the math/rand package: