# re_perf_telemetry Part of the [`rerun`](https://github.com/rerun-io/rerun) family of crates. [![Latest version](https://img.shields.io/crates/v/re_perf_telemetry.svg)](https://crates.io/crates/re_perf_telemetry) [![Documentation](https://docs.rs/re_perf_telemetry/badge.svg)](https://docs.rs/re_perf_telemetry) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) In and out of process telemetry and profiling utilities for Rerun & Redap. Performance telemetry is always disabled by default. It is gated both by a feature flag (`perf_telemetry`) and runtime configuration in the form of environment variables: * `TELEMETRY_ENABLED`: is performance telemetry enabled at all (default: `false`)? When on, the OpenTelemetry SDK is initialized; individual exporters (logs/traces/metrics) only fire when their endpoint env var (or the umbrella `OTEL_EXPORTER_OTLP_ENDPOINT`) is set. * `TRACY_ENABLED`: is the tracy integration enabled (default: `false`)? works even if `TELEMETRY_ENABLED=false`, to reduce noise in measurements. Note that despite the name, this crate also hands all log output to the telemetry backend. ## What `re_perf_telemetry` is a suite of developer tools that integrate with the `tracing` ecosystem and, by extension, make it possible to use: * out-of-process IO-focused profilers such as the [OpenTelemetry](https://opentelemetry.io/) ecosystem (gRPC, trace propagation, distributed tracing, etc) * in-process compute-focused profilers such as [Tracy](https://github.com/wolfpld/tracy) What you can or cannot do with that depends on which project you're working on (Redap, Rerun SDK, Rerun Viewer). See below for more information. ### Redap If you have source access to Rerun Hub check the Readme there. ### Rerun SDK In the Rerun SDK, `re_perf_telemetry` is always disabled by default (feature flagged), and only meant as a developer tool: it never ships with the final user builds. The integration works pretty well for both out-of-process and in-process profiling. We'll use the following script as an example: ```py import rerun as rr client = rr.catalog.CatalogClient("rerun://sandbox.redap.rerun.io") client.dataset_entries() dataset = client.get_dataset_entry(name="droid:raw") # Get the RecordBatch reader from the query view df = dataset.dataframe_query_view( index="real_time", contents={"/camera/ext1": ["VideoFrameReference:timestamp"]}, ).df() print(df.count()) ``` * Example of out-of-process profiling using Jaeger (run `pixi run compose-dev` in the Redap repository to start a Jaeger instance, or `docker run --rm -p 16686:16686 -p 4317:4317 jaegertracing/jaeger:2.11.0` for a standalone instance): ```sh # `perf_telemetry` is a default feature of `rerun_py`, so a plain build is enough for OTel/Jaeger: $ pixi run py-build # If you additionally want Python-side spans (e.g. via the `@with_tracing` decorator in `rerun._tracing`), # install the tracing extra so the OpenTelemetry Python packages are available: $ pixi run uv pip install 'rerun-sdk[tracing]' # Run your script with telemetry enabled and traces pointed at the local Jaeger: $ TELEMETRY_ENABLED=true OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://localhost:4317 # Go to the Jaeger UI (http://localhost:16686/search) to look at the results ``` * Example of in-process profiling using Tracy: ```sh # Build the SDK with Tracy support (the `tracy` Cargo feature on `re_perf_telemetry`): $ pixi run py-build-perf-debug # or `py-build-perf-release` # Run your script with both telemetry and the Tracy integration enabled: $ TELEMETRY_ENABLED=true TRACY_ENABLED=true ``` #### Future work * Integration with [datafusion-tracing](https://github.com/datafusion-contrib/datafusion-tracing) ### Rerun Viewer In the Rerun Viewer, `re_perf_telemetry` is always disabled by default (feature flagged), and only meant as a developer tool: it never ships with the final user builds. The integration only really works with in-process profiling, and even then with caveats (see `Limitations` and `Future work` below). * Example of in-process profiling using Tracy: ```sh # Start the viewer with both telemetry and the Tracy integration enabled: $ TELEMETRY_ENABLED=true TRACY_ENABLED=true pixi run rerun-perf ``` *In this screenshot, I browsed a Redap catalog and then opened one of the recordings. Can you guess when the video decoding happened? 😁* #### Limitations * `puffin` spans are not forwarded to the perf telemetry tools While this is technically do-able (for instance by replacing `puffin` calls with [the `profiling` crate](https://crates.io/crates/profiling)), our `puffin` spans were not implemented with the kind of overhead that the `tracing` involves in mind anyway. A possible future approach would be a native Tracy integration for the Viewer, see `Future work` below. * The viewer will crash during shutdown when perf telemetry is enabled This is actually unrelated to `re_perf_telemetry` AFAICT: the viewer will crash on exit because of what appears to be a design flaw in `tracing-subscriber`'s shutdown implementation, specifically it assumes that all the relevant thread-local state will be dropped in the proper order, when really it won't and there's no way to guarantee that. See . Since this is a very niche feature only meant to be used for deep performance work, I think this is fine for now (and I don't think there's anything we can do from userspace anyhow, this is a pure `tracing` vs. Rust's TLS implementation issue). #### Future work The Rerun Viewer would greatly benefit from a _native_ Tracy integration (i.e. using the Tracy client directly, instead of going through the `tracing` ecosystem). This would not only alleviate the overhead of the `tracing` ecosystem, it would also make it possible to use all the more advanced features of Tracy in the viewer (e.g. GPU spans, framebuffer previews, allocation tracing, contention spans, plots, sub-frames, etc). Check out this [web demo](https://tracy.nereid.pl/) for a taste of what a native Tracy integration can do.