Skip to content

Commit 4a3f299

Browse files
tbraun96hawkw
authored andcommitted
attributes: ensure res and err events inherit target (#2184)
## Motivation Currently, when an `#[instrument]` attribute has an overridden target, the events generated by `ret` and `err` arguments do not inherit that target. For example, if I write ```rust #[tracing::instrument(target = "some_target", ret) fn do_stuff() -> Something { // ... } ``` the `do_stuff` span will have the target "some_target", but the return value event generated by `ret` will have the current module path as its target, and there is no way to change the return value event's target. ## Solution This branch changes the macro expansion for `#[instrument]` with the `ret` and/or `err` arguments so that an overridden target is propagated to the events generated by `ret` and `err`. Fixes #2183
1 parent e0b3f79 commit 4a3f299

File tree

5 files changed

+81
-6
lines changed

5 files changed

+81
-6
lines changed

tracing-attributes/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ quote = "1"
4646
[dev-dependencies]
4747
tracing = { path = "../tracing", version = "0.1" }
4848
tracing-mock = { path = "../tracing-mock", features = ["tokio-test"] }
49+
tracing-subscriber = { path = "../tracing-subscriber", version = "0.3", features = ["env-filter"] }
4950
tokio-test = { version = "0.3.0" }
5051
tracing-core = { path = "../tracing-core", version = "0.1"}
5152
async-trait = "0.1.44"

tracing-attributes/src/expand.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,19 +200,23 @@ fn gen_block<B: ToTokens>(
200200
))
201201
})();
202202

203+
let target = args.target();
204+
203205
let err_event = match args.err_mode {
204206
Some(FormatMode::Default) | Some(FormatMode::Display) => {
205-
Some(quote!(tracing::error!(error = %e)))
207+
Some(quote!(tracing::error!(target: #target, error = %e)))
206208
}
207-
Some(FormatMode::Debug) => Some(quote!(tracing::error!(error = ?e))),
209+
Some(FormatMode::Debug) => Some(quote!(tracing::error!(target: #target, error = ?e))),
208210
_ => None,
209211
};
210212

211213
let ret_event = match args.ret_mode {
212-
Some(FormatMode::Display) => Some(quote!(tracing::event!(#level, return = %x))),
213-
Some(FormatMode::Default) | Some(FormatMode::Debug) => {
214-
Some(quote!(tracing::event!(#level, return = ?x)))
215-
}
214+
Some(FormatMode::Display) => Some(quote!(
215+
tracing::event!(target: #target, #level, return = %x)
216+
)),
217+
Some(FormatMode::Default) | Some(FormatMode::Debug) => Some(quote!(
218+
tracing::event!(target: #target, #level, return = ?x)
219+
)),
216220
_ => None,
217221
};
218222

tracing-attributes/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,9 @@ mod expand;
461461
/// }
462462
/// ```
463463
///
464+
/// If a `target` is specified, both the `ret` and `err` arguments will emit outputs to
465+
/// the declared target (or the default channel if `target` is not specified).
466+
///
464467
/// The `ret` and `err` arguments can be combined in order to record an event if a
465468
/// function returns [`Result::Ok`] or [`Result::Err`]:
466469
///

tracing-attributes/tests/err.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use tracing::subscriber::with_default;
22
use tracing::Level;
33
use tracing_attributes::instrument;
44
use tracing_mock::*;
5+
use tracing_subscriber::filter::EnvFilter;
6+
use tracing_subscriber::layer::SubscriberExt;
57

68
use std::convert::TryFrom;
79
use std::num::TryFromIntError;
@@ -198,3 +200,34 @@ fn test_err_display_default() {
198200
with_default(subscriber, || err().ok());
199201
handle.assert_finished();
200202
}
203+
204+
#[test]
205+
fn test_err_custom_target() {
206+
let filter: EnvFilter = "my_target=error".parse().expect("filter should parse");
207+
let span = span::mock().named("error_span").with_target("my_target");
208+
209+
let (subscriber, handle) = subscriber::mock()
210+
.new_span(span.clone())
211+
.enter(span.clone())
212+
.event(
213+
event::mock()
214+
.at_level(Level::ERROR)
215+
.with_target("my_target"),
216+
)
217+
.exit(span.clone())
218+
.drop_span(span)
219+
.done()
220+
.run_with_handle();
221+
222+
let subscriber = subscriber.with(filter);
223+
224+
with_default(subscriber, || {
225+
let error_span = tracing::error_span!(target: "my_target", "error_span");
226+
227+
{
228+
let _enter = error_span.enter();
229+
tracing::error!(target: "my_target", "This should display")
230+
}
231+
});
232+
handle.assert_finished();
233+
}

tracing-attributes/tests/ret.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ use tracing_mock::*;
44

55
use tracing::{subscriber::with_default, Level};
66
use tracing_attributes::instrument;
7+
use tracing_subscriber::layer::SubscriberExt;
8+
use tracing_subscriber::EnvFilter;
79

810
#[instrument(ret)]
911
fn ret() -> i32 {
1012
42
1113
}
1214

15+
#[instrument(target = "my_target", ret)]
16+
fn ret_with_target() -> i32 {
17+
42
18+
}
19+
1320
#[test]
1421
fn test() {
1522
let span = span::mock().named("ret");
@@ -30,6 +37,33 @@ fn test() {
3037
handle.assert_finished();
3138
}
3239

40+
#[test]
41+
fn test_custom_target() {
42+
let filter: EnvFilter = "my_target=info".parse().expect("filter should parse");
43+
let span = span::mock()
44+
.named("ret_with_target")
45+
.with_target("my_target");
46+
47+
let (subscriber, handle) = subscriber::mock()
48+
.new_span(span.clone())
49+
.enter(span.clone())
50+
.event(
51+
event::mock()
52+
.with_fields(field::mock("return").with_value(&tracing::field::debug(42)))
53+
.at_level(Level::INFO)
54+
.with_target("my_target"),
55+
)
56+
.exit(span.clone())
57+
.drop_span(span)
58+
.done()
59+
.run_with_handle();
60+
61+
let subscriber = subscriber.with(filter);
62+
63+
with_default(subscriber, ret_with_target);
64+
handle.assert_finished();
65+
}
66+
3367
#[instrument(level = "warn", ret)]
3468
fn ret_warn() -> i32 {
3569
42

0 commit comments

Comments
 (0)