From 400cbb72a346c80fcea4d3da7264fd45b3b3debe Mon Sep 17 00:00:00 2001 From: Parth Ajmera Date: Thu, 12 Mar 2026 12:41:13 -0700 Subject: [PATCH 1/3] fix(telemetry): moving histogram buckets from OTel standard to MCP Sem Conv Standard --- internal/telemetry/telemetry.go | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/internal/telemetry/telemetry.go b/internal/telemetry/telemetry.go index a4e195e0fda1..5b336dd92961 100644 --- a/internal/telemetry/telemetry.go +++ b/internal/telemetry/telemetry.go @@ -154,6 +154,45 @@ func newMeterProvider(ctx context.Context, r *resource.Resource, telemetryOTLP s metricOpts = append(metricOpts, metric.WithReader(metric.NewPeriodicReader(gcpExporter))) } + // Configure custom histogram bucket boundaries for duration metrics + // These boundaries follow the OpenTelemetry semantic conventions recommendation: + // https://opentelemetry.io/docs/specs/semconv/general/metrics/#instrument-advice + durationBuckets := []float64{0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300} + + // Create views for duration histograms + operationDurationView := metric.NewView( + metric.Instrument{Name: "mcp.server.operation.duration"}, + metric.Stream{ + Aggregation: metric.AggregationExplicitBucketHistogram{ + Boundaries: durationBuckets, + }, + }, + ) + + sessionDurationView := metric.NewView( + metric.Instrument{Name: "mcp.server.session.duration"}, + metric.Stream{ + Aggregation: metric.AggregationExplicitBucketHistogram{ + Boundaries: durationBuckets, + }, + }, + ) + + toolExecutionDurationView := metric.NewView( + metric.Instrument{Name: "toolbox.tool.execution.duration"}, + metric.Stream{ + Aggregation: metric.AggregationExplicitBucketHistogram{ + Boundaries: durationBuckets, + }, + }, + ) + + metricOpts = append(metricOpts, + metric.WithView(operationDurationView), + metric.WithView(sessionDurationView), + metric.WithView(toolExecutionDurationView), + ) + meterProvider := metric.NewMeterProvider(metricOpts...) return meterProvider, nil } From 77b939def7bd6d7eb410d6cf9093eec6e2f25edc Mon Sep 17 00:00:00 2001 From: Parth Ajmera Date: Thu, 12 Mar 2026 14:44:25 -0700 Subject: [PATCH 2/3] fix(telemetry): gemini feedbacks --- internal/telemetry/telemetry.go | 50 +++++++++++---------------------- 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/internal/telemetry/telemetry.go b/internal/telemetry/telemetry.go index 5b336dd92961..031d0404daba 100644 --- a/internal/telemetry/telemetry.go +++ b/internal/telemetry/telemetry.go @@ -154,44 +154,28 @@ func newMeterProvider(ctx context.Context, r *resource.Resource, telemetryOTLP s metricOpts = append(metricOpts, metric.WithReader(metric.NewPeriodicReader(gcpExporter))) } - // Configure custom histogram bucket boundaries for duration metrics - // These boundaries follow the OpenTelemetry semantic conventions recommendation: - // https://opentelemetry.io/docs/specs/semconv/general/metrics/#instrument-advice + // Configure custom histogram bucket boundaries for duration metrics as per MCP semantic conventions. durationBuckets := []float64{0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300} // Create views for duration histograms - operationDurationView := metric.NewView( - metric.Instrument{Name: "mcp.server.operation.duration"}, - metric.Stream{ - Aggregation: metric.AggregationExplicitBucketHistogram{ - Boundaries: durationBuckets, - }, - }, - ) - - sessionDurationView := metric.NewView( - metric.Instrument{Name: "mcp.server.session.duration"}, - metric.Stream{ - Aggregation: metric.AggregationExplicitBucketHistogram{ - Boundaries: durationBuckets, - }, - }, - ) + durationHistogramNames := []string{ + mcpOperationDurationName, + mcpSessionDurationName, + toolExecutionDurationName, + } - toolExecutionDurationView := metric.NewView( - metric.Instrument{Name: "toolbox.tool.execution.duration"}, - metric.Stream{ - Aggregation: metric.AggregationExplicitBucketHistogram{ - Boundaries: durationBuckets, + views := make([]metric.View, 0, len(durationHistogramNames)) + for _, name := range durationHistogramNames { + views = append(views, metric.NewView( + metric.Instrument{Name: name}, + metric.Stream{ + Aggregation: metric.AggregationExplicitBucketHistogram{ + Boundaries: durationBuckets, + }, }, - }, - ) - - metricOpts = append(metricOpts, - metric.WithView(operationDurationView), - metric.WithView(sessionDurationView), - metric.WithView(toolExecutionDurationView), - ) + )) + } + metricOpts = append(metricOpts, metric.WithView(views...)) meterProvider := metric.NewMeterProvider(metricOpts...) return meterProvider, nil From 7e0d80f4372ada8541c78e621e8eb70e0e1f67e2 Mon Sep 17 00:00:00 2001 From: Parth Ajmera Date: Thu, 12 Mar 2026 14:50:49 -0700 Subject: [PATCH 3/3] fix(telemetry): added link in the comment --- internal/telemetry/telemetry.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/telemetry/telemetry.go b/internal/telemetry/telemetry.go index 031d0404daba..8e39e4046d05 100644 --- a/internal/telemetry/telemetry.go +++ b/internal/telemetry/telemetry.go @@ -155,6 +155,7 @@ func newMeterProvider(ctx context.Context, r *resource.Resource, telemetryOTLP s } // Configure custom histogram bucket boundaries for duration metrics as per MCP semantic conventions. + // Source: https://opentelemetry.io/docs/specs/semconv/gen-ai/mcp/#metric-mcpserversessionduration durationBuckets := []float64{0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 30, 60, 120, 300} // Create views for duration histograms