From 9542e4005c397e93b9fa31a4df1784693473d24d Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 6 Dec 2018 11:22:18 +0100 Subject: [PATCH 1/3] Expose #512 Signed-off-by: beorn7 --- prometheus/registry_test.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/prometheus/registry_test.go b/prometheus/registry_test.go index a96cb10a6..b9d9f13b0 100644 --- a/prometheus/registry_test.go +++ b/prometheus/registry_test.go @@ -21,6 +21,7 @@ package prometheus_test import ( "bytes" + "fmt" "io/ioutil" "math/rand" "net/http" @@ -783,6 +784,11 @@ func TestAlreadyRegistered(t *testing.T) { // same HistogramVec is registered concurrently and the Gather method of the // registry is called concurrently. func TestHistogramVecRegisterGatherConcurrency(t *testing.T) { + labelNames := make([]string, 16) // Need at least 13 to expose #512. + for i := range labelNames { + labelNames[i] = fmt.Sprint("label_", i) + } + var ( reg = prometheus.NewPedanticRegistry() hv = prometheus.NewHistogramVec( @@ -791,7 +797,7 @@ func TestHistogramVecRegisterGatherConcurrency(t *testing.T) { Help: "This helps testing.", ConstLabels: prometheus.Labels{"foo": "bar"}, }, - []string{"one", "two", "three"}, + labelNames, ) labelValues = []string{"a", "b", "c", "alpha", "beta", "gamma", "aleph", "beth", "gimel"} quit = make(chan struct{}) @@ -806,11 +812,11 @@ func TestHistogramVecRegisterGatherConcurrency(t *testing.T) { return default: obs := rand.NormFloat64()*.1 + .2 - hv.WithLabelValues( - labelValues[rand.Intn(len(labelValues))], - labelValues[rand.Intn(len(labelValues))], - labelValues[rand.Intn(len(labelValues))], - ).Observe(obs) + values := make([]string, 0, len(labelNames)) + for range labelNames { + values = append(values, labelValues[rand.Intn(len(labelValues))]) + } + hv.WithLabelValues(values...).Observe(obs) } } } @@ -848,7 +854,7 @@ func TestHistogramVecRegisterGatherConcurrency(t *testing.T) { if len(g) != 1 { t.Error("Gathered unexpected number of metric families:", len(g)) } - if len(g[0].Metric[0].Label) != 4 { + if len(g[0].Metric[0].Label) != len(labelNames)+1 { t.Error("Gathered unexpected number of label pairs:", len(g[0].Metric[0].Label)) } } From fae889635ce96b79dbe0882363682a9bf45b7268 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 6 Dec 2018 11:35:30 +0100 Subject: [PATCH 2/3] Fix #512 Signed-off-by: beorn7 --- prometheus/registry.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/prometheus/registry.go b/prometheus/registry.go index f98c81a86..8301fc8d0 100644 --- a/prometheus/registry.go +++ b/prometheus/registry.go @@ -872,7 +872,13 @@ func checkMetricConsistency( h = hashAddByte(h, separatorByte) // Make sure label pairs are sorted. We depend on it for the consistency // check. - sort.Sort(labelPairSorter(dtoMetric.Label)) + if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) { + // We cannot sort dtoMetric.Label in place as it is immutable by contract. + copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label)) + copy(copiedLabels, dtoMetric.Label) + sort.Sort(labelPairSorter(copiedLabels)) + dtoMetric.Label = copiedLabels + } for _, lp := range dtoMetric.Label { h = hashAdd(h, lp.GetName()) h = hashAddByte(h, separatorByte) From 619eb595bafb3c0b2b1d94c22be1bd74a65c1a7c Mon Sep 17 00:00:00 2001 From: beorn7 Date: Thu, 6 Dec 2018 11:37:34 +0100 Subject: [PATCH 3/3] Simplify an `append` to `copy` Signed-off-by: beorn7 --- prometheus/registry.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prometheus/registry.go b/prometheus/registry.go index 8301fc8d0..b5e70b93f 100644 --- a/prometheus/registry.go +++ b/prometheus/registry.go @@ -909,8 +909,8 @@ func checkDescConsistency( } // Is the desc consistent with the content of the metric? - lpsFromDesc := make([]*dto.LabelPair, 0, len(dtoMetric.Label)) - lpsFromDesc = append(lpsFromDesc, desc.constLabelPairs...) + lpsFromDesc := make([]*dto.LabelPair, len(desc.constLabelPairs), len(dtoMetric.Label)) + copy(lpsFromDesc, desc.constLabelPairs) for _, l := range desc.variableLabels { lpsFromDesc = append(lpsFromDesc, &dto.LabelPair{ Name: proto.String(l),