From 2ea234eef0564aef9d949a0f2f21a1d920ce3b24 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Wed, 3 May 2023 09:35:50 +0100 Subject: [PATCH 1/3] Revert "Remove unnecessary check if label is nil in observeWithExemplar (#1235)" This reverts commit 3ce88f33d1b41965a16cd257009f5431953231b4. Signed-off-by: bwplotka --- prometheus/promhttp/instrument_client.go | 4 +-- prometheus/promhttp/instrument_server.go | 36 ++++++++++++++++++------ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/prometheus/promhttp/instrument_client.go b/prometheus/promhttp/instrument_client.go index 61fc2e3..d3482c4 100644 --- a/prometheus/promhttp/instrument_client.go +++ b/prometheus/promhttp/instrument_client.go @@ -78,7 +78,7 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou for label, resolve := range rtOpts.extraLabelsFromCtx { l[label] = resolve(resp.Request.Context()) } - counter.With(l).(prometheus.ExemplarAdder).AddWithExemplar(1, rtOpts.getExemplarFn(r.Context())) + addWithExemplar(counter.With(l), 1, rtOpts.getExemplarFn(r.Context())) } return resp, err } @@ -122,7 +122,7 @@ func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundT for label, resolve := range rtOpts.extraLabelsFromCtx { l[label] = resolve(resp.Request.Context()) } - obs.With(l).(prometheus.ExemplarObserver).ObserveWithExemplar(time.Since(start).Seconds(), rtOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(start).Seconds(), rtOpts.getExemplarFn(r.Context())) } return resp, err } diff --git a/prometheus/promhttp/instrument_server.go b/prometheus/promhttp/instrument_server.go index 71abd75..3793036 100644 --- a/prometheus/promhttp/instrument_server.go +++ b/prometheus/promhttp/instrument_server.go @@ -28,6 +28,26 @@ import ( // magicString is used for the hacky label test in checkLabels. Remove once fixed. const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa" +// observeWithExemplar is a wrapper for [prometheus.ExemplarAdder.ExemplarObserver], +// which falls back to [prometheus.Observer.Observe] if no labels are provided. +func observeWithExemplar(obs prometheus.Observer, val float64, labels map[string]string) { + if labels == nil { + obs.Observe(val) + return + } + obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels) +} + +// addWithExemplar is a wrapper for [prometheus.ExemplarAdder.AddWithExemplar], +// which falls back to [prometheus.Counter.Add] if no labels are provided. +func addWithExemplar(obs prometheus.Counter, val float64, labels map[string]string) { + if labels == nil { + obs.Add(val) + return + } + obs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels) +} + // InstrumentHandlerInFlight is a middleware that wraps the provided // http.Handler. It sets the provided prometheus.Gauge to the number of // requests currently handled by the wrapped http.Handler. @@ -80,7 +100,7 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - obs.With(l).(prometheus.ExemplarObserver).ObserveWithExemplar(time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) } } @@ -91,7 +111,7 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - obs.With(l).(prometheus.ExemplarObserver).ObserveWithExemplar(time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) } } @@ -130,7 +150,7 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - counter.With(l).(prometheus.ExemplarAdder).AddWithExemplar(1, hOpts.getExemplarFn(r.Context())) + addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) } } @@ -141,7 +161,7 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - counter.With(l).(prometheus.ExemplarAdder).AddWithExemplar(1, hOpts.getExemplarFn(r.Context())) + addWithExemplar(counter.With(l), 1, hOpts.getExemplarFn(r.Context())) } } @@ -183,7 +203,7 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - obs.With(l).(prometheus.ExemplarObserver).ObserveWithExemplar(time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), time.Since(now).Seconds(), hOpts.getExemplarFn(r.Context())) }) next.ServeHTTP(d, r) } @@ -227,7 +247,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - obs.With(l).(prometheus.ExemplarObserver).ObserveWithExemplar(float64(size), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) } } @@ -239,7 +259,7 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - obs.With(l).(prometheus.ExemplarObserver).ObserveWithExemplar(float64(size), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), float64(size), hOpts.getExemplarFn(r.Context())) } } @@ -279,7 +299,7 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler for label, resolve := range hOpts.extraLabelsFromCtx { l[label] = resolve(r.Context()) } - obs.With(l).(prometheus.ExemplarObserver).ObserveWithExemplar(float64(d.Written()), hOpts.getExemplarFn(r.Context())) + observeWithExemplar(obs.With(l), float64(d.Written()), hOpts.getExemplarFn(r.Context())) }) } From b8fdd239b2f259fef654e4890706fad162bc40e9 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Wed, 3 May 2023 09:39:47 +0100 Subject: [PATCH 2/3] Added clarification. Signed-off-by: bwplotka --- prometheus/promhttp/option.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/prometheus/promhttp/option.go b/prometheus/promhttp/option.go index af7403d..5d4383a 100644 --- a/prometheus/promhttp/option.go +++ b/prometheus/promhttp/option.go @@ -66,9 +66,9 @@ func WithExtraMethods(methods ...string) Option { }) } -// WithExemplarFromContext adds allows to put a hook to all counter and histogram metrics. -// If the hook function returns non-nil labels, exemplars will be added for that request, otherwise metric -// will get instrumented without exemplar. +// WithExemplarFromContext allows to inject function that will get exemplar from context that will be put to counter and histogram metrics. +// If the function returns nil labels or the metric does not support exemplars, no exemplar will be added (noop), but +// metric will continue to observe/increment. func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option { return optionApplyFunc(func(o *options) { o.getExemplarFn = getExemplarFn From 4bbb297e54556fd1bcec279b355d049a50fb316e Mon Sep 17 00:00:00 2001 From: Bartlomiej Plotka Date: Wed, 3 May 2023 11:48:04 +0200 Subject: [PATCH 3/3] Cut 1.15.1 (#1266) Signed-off-by: bwplotka --- CHANGELOG.md | 5 +++++ VERSION | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eab132c..3b97d30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ ## What's Changed +* [BUGFIX] Fixed promhttp.Instrument* handlers wrongly trying to attach exemplar to unsupported metrics (e.g. summary), \ +causing panics #1253 + +## What's Changed + * [BUGFIX] Fix issue with atomic variables on ppc64le #1171 * [BUGFIX] Support for multiple samples within same metric #1181 * [BUGFIX] Bump golang.org/x/text to v0.3.8 to mitigate CVE-2022-32149 #1187 diff --git a/VERSION b/VERSION index 141f2e8..ace4423 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.15.0 +1.15.1