Skip to content

Commit 00fb736

Browse files
prefix_logs_with: Ensure the macro works correctly for futures (#11095)
When setting up a tracing span in an async future, it may gets invalidated by any `await` point. The problem is that after continuing a future, it may runs on a different thread where the `span` isn't active anymore. The solution for this is to `instrument` the future properly. --------- Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 37c9bed commit 00fb736

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

prdoc/pr_11095.prdoc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
title: '`prefix_logs_with`: Ensure the macro works correctly for futures'
2+
doc:
3+
- audience: Node Dev
4+
description: |-
5+
When setting up a tracing span in an async future, it may gets invalidated by any `await` point. The problem is that after continuing a future, it may runs on a different thread where the `span` isn't active anymore. The solution for this is to `instrument` the future properly.
6+
crates:
7+
- name: sc-tracing-proc-macro
8+
bump: patch

substrate/client/tracing/proc-macro/src/lib.rs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,40 @@ pub fn prefix_logs_with(arg: TokenStream, item: TokenStream) -> TokenStream {
123123

124124
let syn::ItemFn { attrs, vis, sig, block } = item_fn;
125125

126-
(quote! {
127-
#(#attrs)*
128-
#vis #sig {
129-
let span = #crate_name::tracing::info_span!(
130-
#crate_name::logging::PREFIX_LOG_SPAN,
131-
name = #prefix_expr,
132-
);
133-
let _enter = span.enter();
126+
if sig.asyncness.is_some() {
127+
// For async functions, use `Instrument::instrument` to properly propagate the span
128+
// across `.await` points. Using `span.enter()` in async functions is incorrect because
129+
// the guard can be held across `.await` points where the task may migrate between
130+
// threads, losing the span from thread-local state.
131+
(quote! {
132+
#(#attrs)*
133+
#vis #sig {
134+
let span = #crate_name::tracing::info_span!(
135+
#crate_name::logging::PREFIX_LOG_SPAN,
136+
name = #prefix_expr,
137+
);
134138

135-
#block
136-
}
137-
})
138-
.into()
139+
#crate_name::tracing::Instrument::instrument(async move {
140+
#block
141+
}, span).await
142+
}
143+
})
144+
.into()
145+
} else {
146+
(quote! {
147+
#(#attrs)*
148+
#vis #sig {
149+
let span = #crate_name::tracing::info_span!(
150+
#crate_name::logging::PREFIX_LOG_SPAN,
151+
name = #prefix_expr,
152+
);
153+
let _enter = span.enter();
154+
155+
#block
156+
}
157+
})
158+
.into()
159+
}
139160
}
140161

141162
/// Resolve the correct path for sc_tracing:

0 commit comments

Comments
 (0)