Broken out of #49 (its last unchecked generated-API item) and graduating #29's "OpenTelemetry adapter" roadmap line, per that issue's convention.
What exists today (hooks, no backends)
- Client:
Observe/ObserveAttempts (smithy/client/observability.h) — per-call and per-attempt records.
- Server:
RequestObservation middleware, Guard, HealthEndpoint (smithy/server/middleware.h).
- Tracing: W3C traceparent propagation client-side,
smithy/http/trace_context.h helpers (ParseTraceparent/FormatTraceparent/GenerateTraceContext), server observation carries the incoming traceparent.
Everything maps cleanly onto spans/metrics — but every consumer hand-rolls the export. The production guide documents this posture explicitly: opentelemetry-cpp's dependency tree (protobuf, gRPC for OTLP) would violate the runtime's dep-light rule, so nothing is bundled.
Work items
- Dependency-free Prometheus
/metrics first — the exposition text format needs no client library: a smithy::server::MetricsEndpoint middleware (same composition pattern as HealthEndpoint) aggregating request counts/latencies/status classes from the existing observation hooks, plus a client-side registry fed by ObserveAttempts. Zero new deps, so it can live in :server/:client directly — likely most of the consumer value at a fraction of the OTel effort.
//runtime:otel adapter — bridges the hooks to opentelemetry-cpp behind its own target (the //runtime:http_beast isolation pattern: heavy deps enter the graph only for consumers that opt in). Spans from RequestObservation/ObserveAttempts + traceparent continuity; OTLP exporter config left to the consumer.
- Hook-shape check before committing — the guide gates this on "the hook shapes have survived production use"; the adapter work doubles as that audit. Any hook change lands separately, first, with pins.
- Production-guide observability section gains the turnkey paths (metrics endpoint + OTel wiring), with the compiled-and-mirror-pinned example convention.
Notes
Refs: #49 (origin), #29 (roadmap line graduating), docs/production-guide.md Observability section, PLAN §7c.
Broken out of #49 (its last unchecked generated-API item) and graduating #29's "OpenTelemetry adapter" roadmap line, per that issue's convention.
What exists today (hooks, no backends)
Observe/ObserveAttempts(smithy/client/observability.h) — per-call and per-attempt records.RequestObservationmiddleware,Guard,HealthEndpoint(smithy/server/middleware.h).smithy/http/trace_context.hhelpers (ParseTraceparent/FormatTraceparent/GenerateTraceContext), server observation carries the incoming traceparent.Everything maps cleanly onto spans/metrics — but every consumer hand-rolls the export. The production guide documents this posture explicitly: opentelemetry-cpp's dependency tree (protobuf, gRPC for OTLP) would violate the runtime's dep-light rule, so nothing is bundled.
Work items
/metricsfirst — the exposition text format needs no client library: asmithy::server::MetricsEndpointmiddleware (same composition pattern asHealthEndpoint) aggregating request counts/latencies/status classes from the existing observation hooks, plus a client-side registry fed byObserveAttempts. Zero new deps, so it can live in:server/:clientdirectly — likely most of the consumer value at a fraction of the OTel effort.//runtime:oteladapter — bridges the hooks to opentelemetry-cpp behind its own target (the//runtime:http_beastisolation pattern: heavy deps enter the graph only for consumers that opt in). Spans fromRequestObservation/ObserveAttempts+ traceparent continuity; OTLP exporter config left to the consumer.Notes
docs/development.md).Refs: #49 (origin), #29 (roadmap line graduating),
docs/production-guide.mdObservability section, PLAN §7c.