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 convention —
unstructured_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).
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.goInitMetrics(ctx context.Context, serviceName, serviceVersion string) (shutdown func(context.Context) error, err error)ENABLE_OTEL != "true"→ log "metrics disabled", return no-op shutdown (default for local dev)ENABLE_OTEL=true+OTEL_METRICS_EXPORTER=console→ usestdoutmetricexporter (local dev with visibility)ENABLE_OTEL=true(default) → useotlpmetricgrpcexporter withWithInsecure()(cluster-internal)[0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 15.0, 30.0, 60.0, 120.0, 300.0]seconds (matchesdataverse-mcp-serverPython patterns)otel.SetMeterProvider()service.name,service.versionWire into
cmd/unstructured-data-mcp-server/main.gotelemetry.InitMetrics(ctx, serverName, serverVersion)afterlogger.Init()shutdownMetrics(ctx)for graceful cleanupAdd 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_OTELenv var — matches the team's Pythondataverse-mcp-serverpatternunstructured_data_mcp_*(matchesdataverse_mcp_*)OTEL_EXPORTER_OTLP_ENDPOINTenv var (cluster collector is on port 4311)Verification
make lintpassesmake testpassesENABLE_OTELset → logs "metrics disabled"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).