Skip to content

Replace OpenCensus with OpenTelemetry#2138

Merged
matt0x6F merged 5 commits into
gomods:mainfrom
matt0x6F:replace-opencensus-with-opentelemetry
Jun 19, 2026
Merged

Replace OpenCensus with OpenTelemetry#2138
matt0x6F merged 5 commits into
gomods:mainfrom
matt0x6F:replace-opencensus-with-opentelemetry

Conversation

@matt0x6F

@matt0x6F matt0x6F commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

What is the problem I am trying to address?

#1771: replace OpenCensus with OpenTelemetry. OpenCensus is deprecated and was
sunset in 2023.

#1891 was a draft that took the OpenCensus bridge route — keep the OpenCensus API and
route its spans into an OTel provider. The bridge works but it leaves the deprecated
dependency in the tree and only defers the real migration. Since the instrumentation all
goes through pkg/observ rather than calling OpenCensus directly, going native isn't much
more work than the bridge, so this does that instead and drops OpenCensus entirely.

How is the fix applied?

pkg/observ is a facade — call sites use observ.StartSpan and observ.Record*, not the
OpenCensus API. 45 of the 46 files that start spans only call .End() on what they get
back, so changing StartSpan to return an OTel span leaves them untouched. The migration
is mostly contained to the facade.

  • Traces export over OTLP (gRPC). RegisterExporter builds an otlptracegrpc exporter and
    an SDK TracerProvider, sets it global, and returns a Shutdown for cleanup.
    TraceExporter is now a toggle: otlp or empty. TraceExporterURL is the collector
    endpoint, and when it's empty the standard OTEL_EXPORTER_OTLP_* env vars are honored.
    The default moves from :14268 (Jaeger) to :4317 (OTLP).
  • Metrics go through an OTel MeterProvider backed by a Prometheus reader on the same
    /metrics route. The three custom instruments (cache_lookup_total,
    upstream_fetch_total, upstream_fetch_duration_seconds) keep their names, including the
    proxy_ prefix, so existing scrape configs and dashboards keep working. HTTP server and
    client metrics now come from otelhttp, which means those metric names change to the OTel
    semconv names.
  • ochttp.Handler/ochttp.Transport become otelhttp.NewHandler/otelhttp.NewTransport.
  • stasher.go was the one file reaching under the facade (trace.NewContext); it now uses
    trace.ContextWithSpan.
  • The jaeger, datadog, and stackdriver exporters are gone. Asking for one logs a
    message telling you to use OTLP and carries on — like an unset or unknown exporter, it
    doesn't stop Athens from booting, you just don't get traces.
  • The OpenTelemetry SDK (v1.43.0) was already in the tree as an indirect dependency, so this
    mostly promotes it to direct and drops go.opencensus.io and the three
    contrib.go.opencensus.io/exporter/* modules.

Sampling is configurable. development still samples every trace. Outside it, the new
ATHENS_TRACE_SAMPLING_FRACTION (TraceSamplingFraction in the config file) sets the
fraction of root traces sampled — 0.0 to 1.0, defaulting to 1.0 — via
ParentBased(TraceIDRatioBased(...)), so child spans follow their parent's decision.

What GitHub issue(s) does this PR fix or close?

Fixes #1771, #2026

Note: this drops direct datadog and stackdriver export. Athens still exposes metrics
on /metrics for Prometheus, and traces can reach either through an OTLP collector. Anyone
on ATHENS_TRACE_EXPORTER=datadog/stackdriver needs to point at a collector with
ATHENS_TRACE_EXPORTER=otlp instead — an unsupported value isn't fatal, Athens logs a
message and boots without tracing. The three custom metric names are unchanged; the HTTP
metric names change to the OTel conventions.

OpenCensus is deprecated. Migrate pkg/observ to OpenTelemetry natively
instead of using the bridge (gomods#1891).

- Traces export over OTLP (gRPC). TraceExporter is now an otlp/empty
  toggle; the URL default moves from :14268 to :4317 and OTEL_EXPORTER_OTLP_*
  env vars are honored when it's empty.
- Metrics go through an OTel MeterProvider with a Prometheus reader on the
  same /metrics route. The three custom metrics keep their names (proxy_
  prefix included). HTTP metrics come from otelhttp now, so those names
  change to the semconv names.
- ochttp.Handler/Transport become otelhttp; stasher.go's trace.NewContext
  becomes trace.ContextWithSpan.
- jaeger/datadog/stackdriver are dropped. An unsupported exporter logs a
  message and Athens boots without it, same as before.
- Drop go.opencensus.io and the contrib exporters; promote the OTel SDK
  from indirect to direct.

Fixes gomods#1771
@matt0x6F
matt0x6F requested a review from a team as a code owner June 17, 2026 04:44
@matt0x6F matt0x6F self-assigned this Jun 17, 2026
matt0x6F added 3 commits June 16, 2026 21:49
The observability FAQ still described the old Jaeger/Stackdriver/Datadog
exporters and a walkthrough that won't capture traces now that Athens
speaks OTLP.

- Rewrite the FAQ section around OTLP and note metrics live on /metrics.
- Point the dev compose service at the Jaeger OTLP endpoint and enable
  Jaeger's OTLP receiver (ports 4317/4318).
- Drop the datadog agent service; it's unused now that the Datadog
  exporter is gone.
The non-dev sampler was ParentBased(AlwaysSample), so production sampled
every root span — a behavior change from OpenCensus, which sampled a small
fraction by default. Add a knob instead of hardcoding it.

- New ATHENS_TRACE_SAMPLING_FRACTION (TraceSamplingFraction), 0.0 to 1.0,
  defaulting to 1.0. Outside development the root sampler is
  ParentBased(TraceIDRatioBased(fraction)); development still always samples.
- Document it in config.dev.toml and the testdata fixture.
@matt0x6F
matt0x6F enabled auto-merge (squash) June 19, 2026 02:30
@matt0x6F
matt0x6F merged commit ceac51b into gomods:main Jun 19, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move athens to opentelemetry

2 participants