SIGN IN SIGN UP

Rewatch: add OpenTelemetry tracing support (#8370)

* Introduce OpenTelemetry in rewatch

Add optional OTLP tracing export to rewatch, controlled by the
OTEL_EXPORTER_OTLP_ENDPOINT environment variable. When set, rewatch
exports spans via HTTP OTLP; when unset, tracing is a no-op.

Instrument key build system functions (initialize_build, incremental_build,
compile, parse, clean, format, packages) with tracing spans and attributes
such as module counts and package names.

Restructure main.rs to support telemetry lifecycle (init/flush/shutdown)
and fix show_progress to use >= LevelFilter::Info so -v/-vv don't
suppress progress messages. Also print 'Finished compilation' in
plain_output mode during watch full rebuilds.

Cherry-picked from #8241.

* Improve rewatch span propagation

Propagate parent span through rayon in build.parse so build.parse_file
spans are properly nested under build.parse instead of appearing as
orphaned root spans.

Enrich build.compile_file span with package, suffix, module_system,
and namespace attributes for better observability.

Cherry-picked from #8241.

* Fix compile_file spans not nested under compile_wave in OTEL traces

Tracing spans are thread-local, so compile_file spans created inside
Rayon's par_iter had no parent connection to the compile_wave span on
the main thread. Pass the wave span explicitly via `parent: &wave_span`
to establish the correct parent-child relationship.

Cherry-picked from #8241.

* Add changelog entry for OpenTelemetry support

* Rewatch telemetry: use Path::file_name for PPX span attribute

Replace the ad-hoc split-by-/-or-backslash + take-last-two-parts logic
with Path::file_name, which handles platform separators correctly and
is simpler to reason about. The attribute is informational only, so
reducing to the file name (e.g. `ppx.exe`) is strictly more readable
than the previous two-segment join.

* Rewatch telemetry: gate dirty-module count in build.parse span

The dirty_modules attribute on build.parse required a full iteration
over build_state.modules every parse phase, even when no subscriber
was listening. Gate behind tracing::enabled!(INFO) so incremental
rebuilds don't eat that O(N) scan when telemetry is off.

* Rewatch telemetry: document honored OTEL environment variables

Add a table to the OpenTelemetry section listing the env vars rewatch
responds to and what each does. All config is via standard OTEL vars —
no rewatch-specific knobs — so this is the full surface area.

* Rewatch: impl AsRef<Path> for FolderArg

Lets callers pass folder arguments to functions taking &Path without
the cryptic `as &str` deref-coercion cast:

  Path::new(&build_args.folder as &str)  ->  build_args.folder.as_ref()

FolderArg already had a Deref<Target = str> impl, so this is the
analogous addition for the &Path direction.

* Update telemetry dependency lockfile

Signed-off-by: Jaap Frolich <jfrolich@gmail.com>

* Fix telemetry changelog entry

Signed-off-by: Jaap Frolich <jfrolich@gmail.com>

* Fix telemetry PR link

Signed-off-by: Jaap Frolich <jfrolich@gmail.com>

---------

Signed-off-by: Jaap Frolich <jfrolich@gmail.com>
Co-authored-by: Christoph Knittel <ck@cca.io>
J
Jaap Frolich committed
09df83865682fe145bb45a66b508b9835aeda99e
Parent: 3057278
Committed by GitHub <noreply@github.com> on 4/28/2026, 2:13:42 PM