From e064aa97f19af0dc070387d6a6fa669184640c12 Mon Sep 17 00:00:00 2001 From: beorn7 Date: Fri, 13 Jul 2018 13:43:21 +0200 Subject: [PATCH] Check quantile label during SummaryVec construction Also, document the existing behavior more clearly. Signed-off-by: beorn7 --- prometheus/summary.go | 14 ++++++++++++++ prometheus/summary_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/prometheus/summary.go b/prometheus/summary.go index f7dc85b..83b403c 100644 --- a/prometheus/summary.go +++ b/prometheus/summary.go @@ -105,6 +105,11 @@ type SummaryOpts struct { // with the same fully-qualified name must have the same label names in // their ConstLabels. // + // Due to the way a Summary is represented in the Prometheus text format + // and how it is handled by the Prometheus server internally, “quantile” + // is an illegal label name. Construction of a Summary or SummaryVec + // will panic if this label name is used in ConstLabels. + // // ConstLabels are only used rarely. In particular, do not use them to // attach the same labels to all your metrics. Those use cases are // better covered by target labels set by the scraping Prometheus @@ -402,7 +407,16 @@ type SummaryVec struct { // NewSummaryVec creates a new SummaryVec based on the provided SummaryOpts and // partitioned by the given label names. +// +// Due to the way a Summary is represented in the Prometheus text format and how +// it is handled by the Prometheus server internally, “quantile” is an illegal +// label name. NewSummaryVec will panic if this label name is used. func NewSummaryVec(opts SummaryOpts, labelNames []string) *SummaryVec { + for _, ln := range labelNames { + if ln == quantileLabel { + panic(errQuantileLabelNotAllowed) + } + } desc := NewDesc( BuildFQName(opts.Namespace, opts.Subsystem, opts.Name), opts.Help, diff --git a/prometheus/summary_test.go b/prometheus/summary_test.go index b162ed9..8b1a62e 100644 --- a/prometheus/summary_test.go +++ b/prometheus/summary_test.go @@ -64,6 +64,31 @@ func TestSummaryWithoutObjectives(t *testing.T) { } } +func TestSummaryWithQuantileLabel(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Error("Attempt to create Summary with 'quantile' label did not panic.") + } + }() + _ = NewSummary(SummaryOpts{ + Name: "test_summary", + Help: "less", + ConstLabels: Labels{"quantile": "test"}, + }) +} + +func TestSummaryVecWithQuantileLabel(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Error("Attempt to create SummaryVec with 'quantile' label did not panic.") + } + }() + _ = NewSummaryVec(SummaryOpts{ + Name: "test_summary", + Help: "less", + }, []string{"quantile"}) +} + func benchmarkSummaryObserve(w int, b *testing.B) { b.StopTimer()