User Tracing#223
Merged
Merged
Conversation
mar-cf
commented
Jun 24, 2026
530dd13 to
0b7d4e8
Compare
Contributor
Author
|
@inikulin PTAL |
281f273 to
6a141e5
Compare
TheJokr
reviewed
Jul 9, 2026
Contributor
Author
|
Will update the PR description shortly |
TheJokr
added a commit
that referenced
this pull request
Jul 13, 2026
In #223 we are adding a second tracing pipeline. To avoid clashing metrics between the two, we need to add a label to distinguish them.
TheJokr
reviewed
Jul 13, 2026
c27a28d to
d517d59
Compare
Adds a user-facing span pipeline to `foundations`, parallel to and independent of the existing internal tracing pipeline. Application code emits spans into a separate harness that exports OTLP over HTTP on a Unix domain socket, with per-trace routing metadata (an application-defined `RoutingMetadata`) attached to each span and carried to the endpoint in a configurable header, plus W3C `traceparent` continuation in and out. The public API lives in a dedicated `tracing::user_tracing` module that mirrors the top-level internal-tracing functions (`start_trace`, `span`, `add_span_tags!`, ...), plus a top-level `dual_span` that records into both pipelines at once; `#[span_fn(user = true)]` emits a dual span. The user span rides on `TelemetryContext`, so it propagates across `.await`, spawns, and hooks without manual threading. Two rules shape the surface: the user and internal pipelines are fully independent (separate harnesses, scope stacks, and exporters), and the public surface speaks W3C. Sampling is not configured inside foundations -- per-request activation is driven by the caller. Everything is gated behind the `user-tracing` cargo feature.
Contributor
Author
|
@TheJokr All done, ready to go |
TheJokr
approved these changes
Jul 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This adds a user-facing span pipeline to
foundations, parallel to the existing internal tracing pipeline. Application code can emit spans into a separateUSER_HARNESSthat exports OTLP HTTP over a Unix domain socket (gRPC unsupported) to an OTLP endpoint, with per-trace routing metadata (an application-definedRoutingMetadatatrait) carried on the wire and W3Ctraceparentcontinuation in/out.The design is deliberately a mirror of internal tracing onto a second harness: the user API lives in a dedicated
tracing::user_tracingmodule whose entry points (user_tracing::start_trace,user_tracing::span,user_tracing::add_span_tags!, …) mirror the top-level internal-tracing functions (start_trace,span,add_span_tags!, …), plus a top-leveldual_spanthat records into both pipelines at once. Two hard rules shape the surface:There are two layers to keep separate:
USER_HARNESS+ the exporter, pointed at the OTLP endpoint's socket.user_tracing::start_trace(...)opens a root. Without a root, everyuser_tracing::span/dual_span()/#[span_fn(user = true)]/user_tracing::add_span_tags!is a no-op.User guide
Settings (init-time)
User tracing is configured via one optional block, gated by the
user-tracingfeature and fed to the existingfoundations::telemetry::init:The two settings a consumer must choose are
socket_path(the OTLP endpoint's UDS) androuting_header_name(the header the endpoint reads routing from). Unlike internal tracing, user tracing is off by default (enabled: false) and must be turned on explicitly;max_queue_sizemirrors its internal-tracing equivalent;num_tasksandmax_batch_sizetune the exporter. All others have defaults and can be configured as needed.There is deliberately no sampling configuration here. Unlike internal tracing, the user pipeline is not sampled inside foundations — the inbound
user_tracingcontrol header drives the activation (and therefore sampling) decision upstream.Instrumentation APIs
Toy example covering the whole surface:
Key points for users:
into_context()/TelemetryContext::current()/#[span_fn]all propagate it across.await, even through an internal span's context — no manual threading.dual_span()and#[span_fn(user = true)]open a user span in parallel with an internal span — this matches the guideline to create an internal span for every user span, so a single call feeds both pipelines.dual_spannames both spans from the same argument, so the user span keeps its name even when the internal trace is sampled out (the two pipelines sample independently).TelemetryContext's trace fork only forks the internal trace; user spans created in the forked context stay in the current user trace.