From 4593023f1639f9cf0110b379befdca65bf0cfb20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Jun 2025 01:33:11 +0000 Subject: [PATCH] build(deps): bump github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus Bumps [github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus](https://github.com/grpc-ecosystem/go-grpc-middleware) from 1.0.1 to 1.1.0. - [Release notes](https://github.com/grpc-ecosystem/go-grpc-middleware/releases) - [Commits](https://github.com/grpc-ecosystem/go-grpc-middleware/compare/providers/prometheus/v1.0.1...v1.1.0) --- updated-dependencies: - dependency-name: github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus dependency-version: 1.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +- .../providers/prometheus/options.go | 25 +++++++- .../providers/prometheus/reporter.go | 36 +++++++++-- .../providers/prometheus/server_metrics.go | 59 +++++++++++++++---- .../providers/prometheus/server_options.go | 28 +++++---- vendor/modules.txt | 4 +- 7 files changed, 127 insertions(+), 31 deletions(-) diff --git a/go.mod b/go.mod index 426fc186d4..4fd640760c 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/fsnotify/fsnotify v1.9.0 github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 - github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 github.com/intel/goresctrl v0.8.0 github.com/klauspost/compress v1.18.0 github.com/mdlayher/vsock v1.2.1 diff --git a/go.sum b/go.sum index 04668ad06b..7cbc9911b7 100644 --- a/go.sum +++ b/go.sum @@ -170,8 +170,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= -github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go index bdd171e295..2047b5fe41 100644 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/options.go @@ -46,6 +46,13 @@ func WithSubsystem(subsystem string) CounterOption { } } +// WithNamespace allows you to add a Namespace to Counter metrics. +func WithNamespace(namespace string) CounterOption { + return func(o *prometheus.CounterOpts) { + o.Namespace = namespace + } +} + // A HistogramOption lets you add options to Histogram metrics using With* // funcs. type HistogramOption func(*prometheus.HistogramOpts) @@ -68,7 +75,7 @@ func WithHistogramBuckets(buckets []float64) HistogramOption { // This function is helpful when specifying more than just the buckets, like using NativeHistograms. func WithHistogramOpts(opts *prometheus.HistogramOpts) HistogramOption { // TODO: This isn't ideal either if new fields are added to prometheus.HistogramOpts. - // Maybe we can change the interface to accept abitrary HistogramOpts and + // Maybe we can change the interface to accept arbitrary HistogramOpts and // only make sure to overwrite the necessary fields (name, labels). return func(o *prometheus.HistogramOpts) { o.Buckets = opts.Buckets @@ -95,6 +102,13 @@ func WithHistogramSubsystem(subsystem string) HistogramOption { } } +// WithHistogramNamespace allows you to add a Namespace to histograms metrics. +func WithHistogramNamespace(namespace string) HistogramOption { + return func(o *prometheus.HistogramOpts) { + o.Namespace = namespace + } +} + func typeFromMethodInfo(mInfo *grpc.MethodInfo) grpcType { if !mInfo.IsClientStream && !mInfo.IsServerStream { return Unary @@ -113,6 +127,7 @@ type Option func(*config) type config struct { exemplarFn exemplarFromCtxFn + labelsFn labelsFromCtxFn } func (c *config) apply(opts []Option) { @@ -127,3 +142,11 @@ func WithExemplarFromContext(exemplarFn exemplarFromCtxFn) Option { o.exemplarFn = exemplarFn } } + +// WithLabelsFromContext sets function that will be used to extract labels from context for metrics. +// This should be used in conjunction with WithContextLabels to define which labels to extract. +func WithLabelsFromContext(labelsFn labelsFromCtxFn) Option { + return func(o *config) { + o.labelsFn = labelsFn + } +} diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go index 96c49ad93a..268beb3e61 100644 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/reporter.go @@ -18,6 +18,7 @@ type reporter struct { service, method string kind Kind exemplar prometheus.Labels + contextLabels []string } func (r *reporter) PostCall(err error, rpcDuration time.Duration) { @@ -28,9 +29,13 @@ func (r *reporter) PostCall(err error, rpcDuration time.Duration) { // perform handling of metrics from code switch r.kind { case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverHandledCounter, string(r.typ), r.service, r.method, code.String()) + baseLabels := []string{string(r.typ), r.service, r.method, code.String()} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverHandledCounter, allLabels...) if r.serverMetrics.serverHandledHistogram != nil { - r.observeWithExemplar(r.serverMetrics.serverHandledHistogram, rpcDuration.Seconds(), string(r.typ), r.service, r.method) + histLabels := []string{string(r.typ), r.service, r.method} + allHistLabels := append(histLabels, r.contextLabels...) + r.observeWithExemplar(r.serverMetrics.serverHandledHistogram, rpcDuration.Seconds(), allHistLabels...) } case KindClient: @@ -44,7 +49,9 @@ func (r *reporter) PostCall(err error, rpcDuration time.Duration) { func (r *reporter) PostMsgSend(_ any, _ error, sendDuration time.Duration) { switch r.kind { case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverStreamMsgSent, string(r.typ), r.service, r.method) + baseLabels := []string{string(r.typ), r.service, r.method} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverStreamMsgSent, allLabels...) case KindClient: r.incrementWithExemplar(r.clientMetrics.clientStreamMsgSent, string(r.typ), r.service, r.method) if r.clientMetrics.clientStreamSendHistogram != nil { @@ -56,7 +63,9 @@ func (r *reporter) PostMsgSend(_ any, _ error, sendDuration time.Duration) { func (r *reporter) PostMsgReceive(_ any, _ error, recvDuration time.Duration) { switch r.kind { case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverStreamMsgReceived, string(r.typ), r.service, r.method) + baseLabels := []string{string(r.typ), r.service, r.method} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverStreamMsgReceived, allLabels...) case KindClient: r.incrementWithExemplar(r.clientMetrics.clientStreamMsgReceived, string(r.typ), r.service, r.method) if r.clientMetrics.clientStreamRecvHistogram != nil { @@ -95,11 +104,28 @@ func (rep *reportable) reporter(ctx context.Context, sm *ServerMetrics, cm *Clie r.exemplar = c.exemplarFn(ctx) } + // Extract context labels if labelsFn is configured and we're on server side + if c.labelsFn != nil && kind == KindServer && sm != nil { + contextLabelMap := c.labelsFn(ctx) + // Extract context label values in the order defined by the server metrics + r.contextLabels = make([]string, len(sm.contextLabelNames)) + for i, labelName := range sm.contextLabelNames { + if value, exists := contextLabelMap[labelName]; exists { + r.contextLabels[i] = value + } else { + // Use empty string if label not found in context + r.contextLabels[i] = "" + } + } + } + switch kind { case KindClient: r.incrementWithExemplar(r.clientMetrics.clientStartedCounter, string(r.typ), r.service, r.method) case KindServer: - r.incrementWithExemplar(r.serverMetrics.serverStartedCounter, string(r.typ), r.service, r.method) + baseLabels := []string{string(r.typ), r.service, r.method} + allLabels := append(baseLabels, r.contextLabels...) + r.incrementWithExemplar(r.serverMetrics.serverStartedCounter, allLabels...) } return r, ctx } diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go index def21e5bf1..358d574caf 100644 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_metrics.go @@ -19,6 +19,8 @@ type ServerMetrics struct { serverStreamMsgSent *prometheus.CounterVec // serverHandledHistogram can be nil. serverHandledHistogram *prometheus.HistogramVec + // contextLabelNames stores the names of context labels + contextLabelNames []string } // NewServerMetrics returns a new ServerMetrics object that has server interceptor methods. @@ -27,28 +29,52 @@ type ServerMetrics struct { func NewServerMetrics(opts ...ServerMetricsOption) *ServerMetrics { var config serverMetricsConfig config.apply(opts) + + // Build label names by combining default labels with context labels + defaultLabels := []string{"grpc_type", "grpc_service", "grpc_method"} + defaultLabelsWithCode := []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"} + + startedLabels := append(defaultLabels, config.contextLabels...) + handledLabels := append(defaultLabelsWithCode, config.contextLabels...) + streamLabels := append(defaultLabels, config.contextLabels...) + + // Create histogram if enabled + var serverHandledHistogram *prometheus.HistogramVec + if config.enableHistogram { + histogramLabels := append(defaultLabels, config.contextLabels...) + serverHandledHistogram = prometheus.NewHistogramVec( + histogramOptions(config.histogramOpts).apply(prometheus.HistogramOpts{ + Name: "grpc_server_handling_seconds", + Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.", + Buckets: prometheus.DefBuckets, + }), + histogramLabels, + ) + } + return &ServerMetrics{ serverStartedCounter: prometheus.NewCounterVec( config.counterOpts.apply(prometheus.CounterOpts{ Name: "grpc_server_started_total", Help: "Total number of RPCs started on the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), + }), startedLabels), serverHandledCounter: prometheus.NewCounterVec( config.counterOpts.apply(prometheus.CounterOpts{ Name: "grpc_server_handled_total", Help: "Total number of RPCs completed on the server, regardless of success or failure.", - }), []string{"grpc_type", "grpc_service", "grpc_method", "grpc_code"}), + }), handledLabels), serverStreamMsgReceived: prometheus.NewCounterVec( config.counterOpts.apply(prometheus.CounterOpts{ Name: "grpc_server_msg_received_total", Help: "Total number of RPC stream messages received on the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), + }), streamLabels), serverStreamMsgSent: prometheus.NewCounterVec( config.counterOpts.apply(prometheus.CounterOpts{ Name: "grpc_server_msg_sent_total", Help: "Total number of gRPC stream messages sent by the server.", - }), []string{"grpc_type", "grpc_service", "grpc_method"}), - serverHandledHistogram: config.serverHandledHistogram, + }), streamLabels), + serverHandledHistogram: serverHandledHistogram, + contextLabelNames: config.contextLabels, } } @@ -95,15 +121,28 @@ func (m *ServerMetrics) InitializeMetrics(server reflection.ServiceInfoProvider) func (m *ServerMetrics) preRegisterMethod(serviceName string, mInfo *grpc.MethodInfo) { methodName := mInfo.Name methodType := string(typeFromMethodInfo(mInfo)) + + // Create empty context label values for pre-registration + contextLabels := make([]string, len(m.contextLabelNames)) + for i := range contextLabels { + contextLabels[i] = "" + } + + // Build complete label value arrays + startedLabels := append([]string{methodType, serviceName, methodName}, contextLabels...) + handledLabels := append([]string{methodType, serviceName, methodName}, contextLabels...) + streamLabels := append([]string{methodType, serviceName, methodName}, contextLabels...) + // These are just references (no increments), as just referencing will create the labels but not set values. - _, _ = m.serverStartedCounter.GetMetricWithLabelValues(methodType, serviceName, methodName) - _, _ = m.serverStreamMsgReceived.GetMetricWithLabelValues(methodType, serviceName, methodName) - _, _ = m.serverStreamMsgSent.GetMetricWithLabelValues(methodType, serviceName, methodName) + _, _ = m.serverStartedCounter.GetMetricWithLabelValues(startedLabels...) + _, _ = m.serverStreamMsgReceived.GetMetricWithLabelValues(streamLabels...) + _, _ = m.serverStreamMsgSent.GetMetricWithLabelValues(streamLabels...) if m.serverHandledHistogram != nil { - _, _ = m.serverHandledHistogram.GetMetricWithLabelValues(methodType, serviceName, methodName) + _, _ = m.serverHandledHistogram.GetMetricWithLabelValues(streamLabels...) } for _, code := range interceptors.AllCodes { - _, _ = m.serverHandledCounter.GetMetricWithLabelValues(methodType, serviceName, methodName, code.String()) + handledLabelsWithCode := append(handledLabels, code.String()) + _, _ = m.serverHandledCounter.GetMetricWithLabelValues(handledLabelsWithCode...) } } diff --git a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go index 39d422042c..14340637d1 100644 --- a/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go +++ b/vendor/github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus/server_options.go @@ -10,11 +10,16 @@ import ( ) type exemplarFromCtxFn func(ctx context.Context) prometheus.Labels +type labelsFromCtxFn func(metadata context.Context) prometheus.Labels type serverMetricsConfig struct { counterOpts counterOptions - // serverHandledHistogram can be nil. - serverHandledHistogram *prometheus.HistogramVec + // histogramOpts stores the options for creating the histogram with dynamic labels + histogramOpts histogramOptions + // enableHistogram indicates whether histogram should be created + enableHistogram bool + // contextLabels defines the names of dynamic labels to be extracted from context + contextLabels []string } type ServerMetricsOption func(*serverMetricsConfig) @@ -36,13 +41,16 @@ func WithServerCounterOptions(opts ...CounterOption) ServerMetricsOption { // Histogram metrics can be very expensive for Prometheus to retain and query. func WithServerHandlingTimeHistogram(opts ...HistogramOption) ServerMetricsOption { return func(o *serverMetricsConfig) { - o.serverHandledHistogram = prometheus.NewHistogramVec( - histogramOptions(opts).apply(prometheus.HistogramOpts{ - Name: "grpc_server_handling_seconds", - Help: "Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.", - Buckets: prometheus.DefBuckets, - }), - []string{"grpc_type", "grpc_service", "grpc_method"}, - ) + o.histogramOpts = opts + o.enableHistogram = true + } +} + +// WithContextLabels configures the server metrics to include dynamic labels extracted from context. +// The provided label names will be added to all server metrics as dynamic labels. +// Use WithLabelsFromContext in the interceptor options to specify how to extract these labels from context. +func WithContextLabels(labelNames ...string) ServerMetricsOption { + return func(o *serverMetricsConfig) { + o.contextLabels = labelNames } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 07296c13ac..15a684d491 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -313,8 +313,8 @@ github.com/google/uuid # github.com/gorilla/websocket v1.5.0 ## explicit; go 1.12 github.com/gorilla/websocket -# github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 -## explicit; go 1.19 +# github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 +## explicit; go 1.21 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus # github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 ## explicit; go 1.19