Skip to content

feat: instrument whoami with OpenTelemetry traces, metrics, and logs#158

Open
zalbiraw wants to merge 3 commits into
traefik:masterfrom
zalbiraw:feat/otel-instrumentation
Open

feat: instrument whoami with OpenTelemetry traces, metrics, and logs#158
zalbiraw wants to merge 3 commits into
traefik:masterfrom
zalbiraw:feat/otel-instrumentation

Conversation

@zalbiraw

Copy link
Copy Markdown

What

Instruments whoami with OpenTelemetry, configured entirely through the standard OTEL_* environment variables. whoami can now emit traces, metrics, and logs (including per-request access logs) to any OTLP backend.

How it's controlled

Each signal is controlled independently by its standard exporter variable:

Variable Default Behaviour
OTEL_LOGS_EXPORTER console console prints to stdout, otlp ships logs, none disables
OTEL_TRACES_EXPORTER none set to otlp (or console) to emit traces
OTEL_METRICS_EXPORTER none set to otlp (or console) to emit metrics

Logs print to stdout out of the box; traces and metrics are opt-in. Endpoint, protocol, service name, and resource attributes use the usual OTEL_EXPORTER_OTLP_*, OTEL_SERVICE_NAME, and OTEL_RESOURCE_ATTRIBUTES variables (exporter selection via contrib/exporters/autoexport).

What gets emitted

  • Traces — a server span per HTTP request (otelhttp) and per gRPC call (otelgrpc).
  • Metrics — HTTP server metrics (http.server.*), gRPC server metrics (rpc.server.*), and a custom whoami.requests counter labelled by method and status.
  • Logs — application logs plus a structured access log per request (method, path, status, response size, duration), emitted via the OpenTelemetry Logs SDK. Access logs run inside the request span, so each record carries the active trace and span IDs.

Other changes

  • Replaces the deprecated golang.org/x/net/http2/h2c with the native Go 1.24 HTTP/2 cleartext support (http.Server.Protocols + SetUnencryptedHTTP2), keeping the plaintext gRPC endpoint working.
  • Drains in-flight requests on SIGINT/SIGTERM so batched telemetry is flushed on shutdown.
  • go.mod stays at go 1.24; the existing CI workflow and .golangci.yml are untouched. Dependencies are pinned to a coordinated, go-1.24-compatible OpenTelemetry release set, and gRPC stays at its current version.

Verification

  • go build, go test, go vet, and golangci-lint (the pinned v2.1.2) all pass; go mod tidy is diff-free.
  • End-to-end against an OTLP collector: HTTP and gRPC spans, http.server.* / rpc.server.* / whoami.requests metrics, and access-log records with non-zero trace IDs all arrive. With no OTEL_* vars set, structured logs (incl. access logs) print to stdout and nothing is shipped.

zalbiraw and others added 3 commits June 17, 2026 13:43
Add OpenTelemetry instrumentation configured entirely through the standard
OTEL_* environment variables, so whoami can ship traces, metrics, and logs
(including per-request access logs) to any OTLP backend.

- Traces: a server span per HTTP request (otelhttp) and per gRPC call
  (otelgrpc).
- Metrics: HTTP server metrics (http.server.*), gRPC server metrics
  (rpc.server.*), and a custom whoami.requests counter by method/status.
- Logs: application and structured access logs are emitted through the
  OpenTelemetry Logs SDK. Access logs run inside the request span, so each
  record carries the active trace and span IDs.

Each signal is controlled independently by its standard exporter variable.
Logs default to the console (stdout) exporter so whoami prints structured
logs out of the box; traces and metrics are opt-in (OTEL_TRACES_EXPORTER /
OTEL_METRICS_EXPORTER, e.g. set to "otlp"). Endpoint, protocol, service name,
and resource attributes use the usual OTEL_EXPORTER_OTLP_* variables.

Also replace the deprecated golang.org/x/net/http2/h2c with the native Go 1.24
HTTP/2 cleartext support, and drain in-flight requests on SIGINT/SIGTERM so
batched telemetry is flushed on shutdown.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Main job installs the latest stable Go (now 1.26), but the pinned
golangci-lint v2.1.2 is built with Go 1.24 and panics when type-checking a
newer stdlib ("file requires newer Go version go1.26"). Pin this job to Go
1.24 — the module's go directive — so the linter works. The Go matrix
workflow still builds and tests against stable and oldstable across all OSes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Restore whoami's original default-quiet behavior: per-request access logs are
emitted only when the `verbose` flag is set, so stdout stays minimal by default
and shows access logs just like the pre-OpenTelemetry verbose mode did. Access
logs still flow through OpenTelemetry (stdout by default, or OTLP when
configured) and carry the active trace and span IDs.

The whoami.requests metric is unaffected and is still recorded for every
request regardless of verbosity.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@nmengin nmengin added kind/enhancement a new or improved feature. status/2-needs-review labels Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants