Conversation
WithSpanExecutor
This comment was marked as outdated.
This comment was marked as outdated.
Signed-off-by: katelyn martin <git@katelyn.world>
54227ba to
13ebd15
Compare
This comment was marked as resolved.
This comment was marked as resolved.
WithSpanExecutor13ebd15 to
abbdef1
Compare
7277f06 to
7899d89
Compare
see #322 for more information. this commit introduces an additional `Executor` implementation to accompany the `CurrentSpanExecutor` that executes spawned futures within the current span at time of execution. this would provide an alternative for users that wish to provide tracing information, but do not want to run background futures in the current span, which can interfere with some observability systems. Signed-off-by: katelyn martin <git@katelyn.world>
this propagates the construction span. Signed-off-by: katelyn martin <git@katelyn.world>
Signed-off-by: katelyn martin <git@katelyn.world>
Signed-off-by: katelyn martin <git@katelyn.world>
now that we have added documentation to this submodule with information about selecting an executor, along with examples, we should make this submodule public so that users can see it. Signed-off-by: katelyn martin <git@katelyn.world>
Signed-off-by: katelyn martin <git@katelyn.world>
7899d89 to
4965d98
Compare
this is an example similar to `client.rs` that makes use of the tracing functionality in `rt::tracing`. this example uses the current span executor, and runs the client in an info-level span to demonstrate the functionality. the `fmt` feature is added to our development dependency upon `tracing_subscriber`. when run against the server example, the logs look like the following: ``` ; cargo run --example client_tracing --features 'client client-legacy http1 tokio tracing' -- http://127.0.0.1:8000 2026-09-21T18:12:10.840038Z INFO client_tracing: tracing subscriber initialized 2026-09-21T18:12:10.840072Z INFO client_tracing: parsed URL url=http://127.0.0.1:8000/ 2026-09-21T18:12:10.840137Z TRACE sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::pool: checkout waiting for idle connection: ("http", 127.0.0.1:8000) 2026-09-21T18:12:10.840181Z TRACE sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::connect::http: Http::connect; scheme=Some("http"), host=Some("127.0.0.1"), port=Some(Port(8000)) 2026-09-21T18:12:10.840199Z DEBUG sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::connect::http: connecting to 127.0.0.1:8000 2026-09-21T18:12:10.840335Z DEBUG sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::connect::http: connected to 127.0.0.1:8000 2026-09-21T18:12:10.840369Z TRACE sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::client: http1 handshake complete, spawning background dispatcher task 2026-09-21T18:12:10.840386Z TRACE sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::client: waiting for connection to be ready 2026-09-21T18:12:10.840422Z TRACE sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::client: connection is ready 2026-09-21T18:12:10.840432Z TRACE sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::pool: checkout dropped for ("http", 127.0.0.1:8000) 2026-09-21T18:12:10.840666Z TRACE sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::pool: put; add idle connection for ("http", 127.0.0.1:8000) 2026-09-21T18:12:10.840689Z DEBUG sending request{url=http://127.0.0.1:8000/}: hyper_util::client::legacy::pool: pooling idle connection for ("http", 127.0.0.1:8000) 2026-09-21T18:12:10.840709Z INFO client_tracing: received response resp.version=HTTP/1.1 resp.status=200 OK resp.body=Hello, world! ``` this demonstrates the informative context (the destination url in this case) that is attached to background tasks spawned by the client. Signed-off-by: katelyn martin <git@katelyn.world>
cratelyn
left a comment
There was a problem hiding this comment.
💬 notes for reviewers
There was a problem hiding this comment.
see the pr description for logs from this example.
| /// See the module-level documentation of [`rt::tracing`](crate::rt::tracing) | ||
| /// for more information about propagating [`tracing`] spans to spawned tasks. |
There was a problem hiding this comment.
i've added a link to the module-level documentation where there is more information about choosing a particular executor. we still mention CurrentSpanExecutor to provide a likely workable default for most users.
| } | ||
|
|
||
| #[test] | ||
| fn mk_span_executor_current_propagates_causal_span_relationships() { |
There was a problem hiding this comment.
this is a test to show that we can spawn background tasks that "follow from" the current span. there is a bit of boilerplate to record and check this, since it isn't visible through Span's public interface: https://docs.rs/tracing/latest/tracing/struct.Span.html
| //! Runtime components for use with [`tracing`]. | ||
| //! | ||
| //! This module provides [`Executor`] implementations that configure | ||
| //! instrumentation of spawned futures. These [`Executor`]s can propagate | ||
| //! tracing [`Span`]s to futures spawned onto the async runtime. See the | ||
| //! crate-level documentation of [`tracing`] for [more information] about spans. | ||
| //! | ||
| //! # Choosing an [`Executor`]. | ||
| //! | ||
| //! Hyper spawns [`Future`]s onto an [`Executor`], to avoid tightly coupling | ||
| //! APIs to any particular async runtime. This includes background tasks that | ||
| //! might help service I/O for the lifetime of a connection, for example. | ||
| //! | ||
| //! Some [`Subscriber`][tracing::subscriber] implementations have different | ||
| //! semantics regarding the lifecycle of [`Span`]s. Integrations with | ||
| //! OpenTelemetry collectors, for example, might not emit the events within | ||
| //! the context of a span until it is closed. Conversely, subscribers that | ||
| //! print traces to the terminal may not have to contend with these details when | ||
| //! instrumenting long-lived tasks that run in the background. | ||
| //! | ||
| //! This module provides different executors to help pass tracing context in | ||
| //! the manner appropriate for your application. For most typical applications, | ||
| //! [`CurrentSpanExecutor<E>`] should suffice. |
There was a problem hiding this comment.
because tracing spans can be a little bit tricky, i tried documenting this in a legible and descriptive way, and including examples (below) for some common span propagation strategies. open to suggestions about how to make this more helpful!
📜 background
see #322 for more information.
in #166,
hyper_util::rt::TokioExecutor<E>began propagating the currently activetracing::Spanto spawned tasks whenhyper::rt::Executor::execute()is called.hyperium/hyper#3904 reports how this has since caused some issues, in part because some observability systems do not export spans until they are closed. in #322, we removed this behavior from
hyper_util::rt::TokioExecutor<E>, with a temporary feature flag that can be used to preserve the previous behavior.📊
rt::tracingthis branch introduces a new submodule,
hyper_util::rt::tracing. this submodule contains a collection ofExecutewrappers to allow tracing spans to be propagated according to a few different common strategies.WithSpanExecutor<E>instruments background tasks with a provided span.CurrentSpanExecutor<E>instruments background tasks with the current span whenexecute()is called.MkSpanExecutor<E, F>instruments background tasks with a span created by a provided callback.this submodule is gated by the
#[cfg(tracing)]feature flag.🌱 Example
this branch adds an example similar to
client.rsthat makes use of the tracing functionality inrt::tracing. this example uses the current span executor, and runs the client in an info-level span to demonstrate the functionality.the
fmtfeature is added to our development dependency upontracing_subscriber.when run against the server example, the logs look like the following:
this demonstrates the informative context (the destination url in this case) that is attached to background tasks spawned by the client.