Skip to content

feature: exemplar support for promhttp #854

@bwplotka

Description

@bwplotka

Problem Statement

I am building HTTP client and server instrumentation for both metrics and tracing, but it's currently hard/impossible to compose both using promhttp

This will become more and more "normal" so wonder if there a good way to extend promhttp to Instrument with Exermplars. Right now I have to do things on my own:

	return promhttp.InstrumentRoundTripperInFlight(
		ins.requestsInFlight.WithLabelValues("target"),
		// TODO(bwplotka): Can't use promhttp.InstrumentRoundTripperCounter or  promhttp.InstrumentRoundTripperDuration, propose exemplars feature.
		promhttp.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
			now := time.Now()
			resp, err := next.RoundTrip(req)
			if err != nil {
				return resp, err
			}

			cntr := ins.requestsTotal.WithLabelValues(targetName, strings.ToLower(req.Method), fmt.Sprintf("%d", resp.StatusCode))
			observer := ins.requestDuration.WithLabelValues(targetName, strings.ToLower(req.Method), fmt.Sprintf("%d", resp.StatusCode))
			// If we find a TraceID from OpenTelemetry we'll expose it as Exemplar.
			if spanCtx := trace.SpanContextFromContext(req.Context()); spanCtx.HasTraceID() {
				traceID := prometheus.Labels{"traceID": spanCtx.TraceID().String()}

				cntr.(prometheus.ExemplarAdder).AddWithExemplar(1, traceID)
				observer.(prometheus.ExemplarObserver).ObserveWithExemplar(time.Since(now).Seconds(), traceID)
				return resp, err
			}

			cntr.Inc()
			observer.Observe(time.Since(now).Seconds())
			return resp, err
		}),
	)

Proposal

Maybe something similar to promauto.With?


promhttp.WithExemplarFunc(fn func(ctx context.Context) prometheus.Labels).InstrumentRoundTripperCounter(....)

WDYT? @beorn7 (:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions