Skip to content

[Observability 1/10] Add OTEL metrics foundation — telemetry package + main.go wiring #308

Description

@concaf

Context

This is the first issue in the observability series. The MCP server currently has zero metrics instrumentation. We are adding OpenTelemetry metrics that export via OTLP to the existing OTEL Collector on the cluster, which forwards to Datadog.

This issue sets up the foundation that all subsequent metrics issues depend on.

Scope

Create pkg/telemetry/telemetry.go

  • InitMetrics(ctx context.Context, serviceName, serviceVersion string) (shutdown func(context.Context) error, err error)
  • Three modes controlled by env vars:
    • ENABLE_OTEL != "true" → log "metrics disabled", return no-op shutdown (default for local dev)
    • ENABLE_OTEL=true + OTEL_METRICS_EXPORTER=console → use stdoutmetric exporter (local dev with visibility)
    • ENABLE_OTEL=true (default) → use otlpmetricgrpc exporter with WithInsecure() (cluster-internal)
  • Set custom histogram bucket views: [0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 15.0, 30.0, 60.0, 120.0, 300.0] seconds (matches dataverse-mcp-server Python patterns)
  • Set global MeterProvider via otel.SetMeterProvider()
  • Resource attributes: service.name, service.version

Wire into cmd/unstructured-data-mcp-server/main.go

  • Call telemetry.InitMetrics(ctx, serverName, serverVersion) after logger.Init()
  • Defer shutdownMetrics(ctx) for graceful cleanup

Add Go dependencies

  • go.opentelemetry.io/otel (promote from indirect)
  • go.opentelemetry.io/otel/metric (promote from indirect)
  • go.opentelemetry.io/otel/sdk (promote from indirect)
  • go.opentelemetry.io/otel/sdk/metric (new)
  • go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc (new)
  • go.opentelemetry.io/otel/exporters/stdout/stdoutmetric (new)

Design decisions

  • ENABLE_OTEL env var — matches the team's Python dataverse-mcp-server pattern
  • Naming conventionunstructured_data_mcp_* (matches dataverse_mcp_*)
  • OTLP endpoint — reads standard OTEL_EXPORTER_OTLP_ENDPOINT env var (cluster collector is on port 4311)

Verification

  • make lint passes
  • make test passes
  • Server starts without ENABLE_OTEL set → logs "metrics disabled"
  • Server starts with ENABLE_OTEL=true OTEL_METRICS_EXPORTER=console → no crash (no metrics recorded yet)

Blocked by

Nothing — this is the first issue.

Blocks

All subsequent observability issues (#2-#6).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgoPull requests that update go codeobservabilityMetrics, tracing, alerting, and monitoring

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions