Context
RisingWave is migrating from tokio-tracing + tracing-opentelemetry to fastrace for distributed tracing (PR risingwavelabs/risingwave#25554). One area where we found no fastrace equivalent is stream-level span instrumentation.
Problem
tracing_futures provides Instrument trait that works with futures::Stream — entering/exiting a span on each poll_next. RisingWave uses this pattern extensively for long-lived streaming pipelines:
// Current pattern using tracing_futures
use tracing::Instrument;
some_stream.instrument(tracing::info_span!("stream_processing"))
We also have a custom instrument_with that creates a new span per yielded item (useful for per-message tracing in long-lived streams):
stream.instrument_with(|| tracing::info_span!("process_item"))
fastrace provides FutureExt::in_span() for futures, but there is no equivalent for futures::Stream. The enter_on_poll feature works for futures but not streams.
Current workaround
We retained tracing::Span-based stream instrumentation as-is, running in parallel with fastrace spans. This means stream-level spans go through tokio-tracing (fmt log output) but not through fastrace (OTLP export).
Proposal
Consider adding a StreamExt equivalent in fastrace:
pub trait StreamExt: futures::Stream + Sized {
/// Instrument the stream with a span — entered on each poll_next.
fn in_span(self, span: Span) -> InSpanStream<Self>;
/// Instrument the stream with a new span per yielded item.
fn in_span_with<F>(self, make_span: F) -> WithSpanStream<Self, F>
where
F: FnMut() -> Span;
}
This would complete the async instrumentation story: FutureExt::in_span for futures + StreamExt::in_span for streams.
References
Context
RisingWave is migrating from
tokio-tracing + tracing-opentelemetryto fastrace for distributed tracing (PR risingwavelabs/risingwave#25554). One area where we found no fastrace equivalent is stream-level span instrumentation.Problem
tracing_futuresprovidesInstrumenttrait that works withfutures::Stream— entering/exiting a span on eachpoll_next. RisingWave uses this pattern extensively for long-lived streaming pipelines:We also have a custom
instrument_withthat creates a new span per yielded item (useful for per-message tracing in long-lived streams):fastrace provides
FutureExt::in_span()for futures, but there is no equivalent forfutures::Stream. Theenter_on_pollfeature works for futures but not streams.Current workaround
We retained
tracing::Span-based stream instrumentation as-is, running in parallel with fastrace spans. This means stream-level spans go through tokio-tracing (fmt log output) but not through fastrace (OTLP export).Proposal
Consider adding a
StreamExtequivalent in fastrace:This would complete the async instrumentation story:
FutureExt::in_spanfor futures +StreamExt::in_spanfor streams.References
tracing_futures::Instrument— the existing tokio-tracing equivalentFutureExt::in_span()— the future equivalentsrc/connector/src/parser/mod.rs,src/frontend/src/scheduler/local.rs