From db2450f6c4000893dc44db51d9a94d8aae326d18 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Dec 2025 19:40:32 +0000 Subject: [PATCH 1/2] Initial plan From f57ee1f1b2c5eefdf6f1e4883f0409e2989fe10b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 4 Dec 2025 19:46:33 +0000 Subject: [PATCH 2/2] Fix metric naming inconsistencies and typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove _total suffix from counter names (auto-added by Prometheus exporter) - Add metric.WithUnit("s") for histogram durations instead of _seconds suffix - Fix spelling: "exection" → "execution" in docs - Update middleware chain comment to include telemetry Co-authored-by: jerm-dro <10532181+jerm-dro@users.noreply.github.com> --- docs/operator/virtualmcpserver-observability.md | 2 +- pkg/vmcp/server/server.go | 2 +- pkg/vmcp/server/telemetry.go | 17 +++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/operator/virtualmcpserver-observability.md b/docs/operator/virtualmcpserver-observability.md index 8e6bdd791b..80235abe14 100644 --- a/docs/operator/virtualmcpserver-observability.md +++ b/docs/operator/virtualmcpserver-observability.md @@ -39,7 +39,7 @@ the workflow name as an attribute. ## Distributed Tracing -The vMCP creates spans for each individual backend operation as well as workflow executions, enabling the attribution of workflow exection errors or latency to specific tool calls. +The vMCP creates spans for each individual backend operation as well as workflow executions, enabling the attribution of workflow execution errors or latency to specific tool calls. ## Configuration diff --git a/pkg/vmcp/server/server.go b/pkg/vmcp/server/server.go index fd7685da36..151a4da9cf 100644 --- a/pkg/vmcp/server/server.go +++ b/pkg/vmcp/server/server.go @@ -375,7 +375,7 @@ func (s *Server) Start(ctx context.Context) error { logger.Info("RFC 9728 OAuth discovery endpoints enabled at /.well-known/") } - // MCP endpoint - apply middleware chain: auth → discovery + // MCP endpoint - apply middleware chain: auth → discovery → telemetry var mcpHandler http.Handler = streamableServer if s.config.TelemetryProvider != nil { diff --git a/pkg/vmcp/server/telemetry.go b/pkg/vmcp/server/telemetry.go index b79d12494a..07a53e5e1b 100644 --- a/pkg/vmcp/server/telemetry.go +++ b/pkg/vmcp/server/telemetry.go @@ -38,15 +38,19 @@ func monitorBackends( } backendCount.Record(ctx, int64(len(backends))) - requestsTotal, err := meter.Int64Counter("toolhive_vmcp_backend_requests_total", metric.WithDescription("Total number of requests per backend")) + requestsTotal, err := meter.Int64Counter("toolhive_vmcp_backend_requests", metric.WithDescription("Total number of requests per backend")) if err != nil { return nil, fmt.Errorf("failed to create requests total counter: %w", err) } - errorsTotal, err := meter.Int64Counter("toolhive_vmcp_backend_errors_total", metric.WithDescription("Total number of errors per backend")) + errorsTotal, err := meter.Int64Counter("toolhive_vmcp_backend_errors", metric.WithDescription("Total number of errors per backend")) if err != nil { return nil, fmt.Errorf("failed to create errors total counter: %w", err) } - requestsDuration, err := meter.Float64Histogram("toolhive_vmcp_backend_requests_duration", metric.WithDescription("Duration of requests in seconds per backend")) + requestsDuration, err := meter.Float64Histogram( + "toolhive_vmcp_backend_requests_duration", + metric.WithDescription("Duration of requests in seconds per backend"), + metric.WithUnit("s"), + ) if err != nil { return nil, fmt.Errorf("failed to create requests duration histogram: %w", err) } @@ -142,7 +146,7 @@ func monitorWorkflowExecutors( meter := meterProvider.Meter(instrumentationName) executionsTotal, err := meter.Int64Counter( - "toolhive_vmcp_workflow_executions_total", + "toolhive_vmcp_workflow_executions", metric.WithDescription("Total number of workflow executions"), ) if err != nil { @@ -150,7 +154,7 @@ func monitorWorkflowExecutors( } errorsTotal, err := meter.Int64Counter( - "toolhive_vmcp_workflow_errors_total", + "toolhive_vmcp_workflow_errors", metric.WithDescription("Total number of workflow execution errors"), ) if err != nil { @@ -158,8 +162,9 @@ func monitorWorkflowExecutors( } executionDuration, err := meter.Float64Histogram( - "toolhive_vmcp_workflow_duration_seconds", + "toolhive_vmcp_workflow_duration", metric.WithDescription("Duration of workflow executions in seconds"), + metric.WithUnit("s"), ) if err != nil { return nil, fmt.Errorf("failed to create workflow duration histogram: %w", err)