attributes: add skip_all (#1548)

Using `#[instrument(skip_all)]` is equivalent to `#[instrument(skip(foo,
bar..))]` for all the parameters.
This commit is contained in:
Jeremy Fitzhardinge 2021-09-12 09:57:21 -07:00 committed by GitHub
parent 0ab63ef5cb
commit 665170ddc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 3 deletions

View File

@ -166,10 +166,13 @@ use syn::{
/// - multiple argument names can be passed to `skip`.
/// - arguments passed to `skip` do _not_ need to implement `fmt::Debug`.
///
/// You can also use `skip_all` to skip all arguments.
///
/// ## Examples
///
/// ```
/// # use tracing_attributes::instrument;
/// # use std::collections::HashMap;
/// // This type doesn't implement `fmt::Debug`!
/// struct NonDebug;
///
@ -178,6 +181,12 @@ use syn::{
/// fn my_function(arg: usize, non_debug: NonDebug) {
/// // ...
/// }
///
/// // These arguments are huge
/// #[instrument(skip_all)]
/// fn my_big_data_function(large: Vec<u8>, also_large: HashMap<String, String>) {
/// // ...
/// }
/// ```
///
/// Skipping the `self` parameter:
@ -257,8 +266,8 @@ use syn::{
/// }
/// ```
///
/// This can be used in conjunction with `skip` to record only some fields of a
/// struct:
/// This can be used in conjunction with `skip` or `skip_all` to record only
/// some fields of a struct:
/// ```
/// # use tracing_attributes::instrument;
/// // Remember the struct with the very large `data` field from the earlier
@ -644,7 +653,7 @@ fn gen_block(
let quoted_fields: Vec<_> = param_names
.iter()
.filter(|(param, _)| {
if args.skips.contains(param) {
if args.skip_all || args.skips.contains(param) {
return false;
}
@ -754,6 +763,7 @@ struct InstrumentArgs {
name: Option<LitStr>,
target: Option<LitStr>,
skips: HashSet<Ident>,
skip_all: bool,
fields: Option<Fields>,
err: bool,
/// Errors describing any unrecognized parse inputs that we skipped.
@ -872,8 +882,20 @@ impl Parse for InstrumentArgs {
if !args.skips.is_empty() {
return Err(input.error("expected only a single `skip` argument"));
}
if args.skip_all {
return Err(input.error("expected either `skip` or `skip_all` argument"));
}
let Skips(skips) = input.parse()?;
args.skips = skips;
} else if lookahead.peek(kw::skip_all) {
if args.skip_all {
return Err(input.error("expected only a single `skip_all` argument"));
}
if !args.skips.is_empty() {
return Err(input.error("expected either `skip` or `skip_all` argument"));
}
let _ = input.parse::<kw::skip_all>()?;
args.skip_all = true;
} else if lookahead.peek(kw::fields) {
if args.fields.is_some() {
return Err(input.error("expected only a single `fields` argument"));
@ -1158,6 +1180,7 @@ fn param_names(pat: Pat, record_type: RecordType) -> Box<dyn Iterator<Item = (Id
mod kw {
syn::custom_keyword!(fields);
syn::custom_keyword!(skip);
syn::custom_keyword!(skip_all);
syn::custom_keyword!(level);
syn::custom_keyword!(target);
syn::custom_keyword!(name);

View File

@ -96,6 +96,9 @@ fn skip() {
#[instrument(target = "my_target", level = "debug", skip(_arg2, _arg3))]
fn my_fn(arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {}
#[instrument(target = "my_target", level = "debug", skip_all)]
fn my_fn2(_arg1: usize, _arg2: UnDebug, _arg3: UnDebug) {}
let span = span::mock()
.named("my_fn")
.at_level(Level::DEBUG)
@ -105,6 +108,12 @@ fn skip() {
.named("my_fn")
.at_level(Level::DEBUG)
.with_target("my_target");
let span3 = span::mock()
.named("my_fn2")
.at_level(Level::DEBUG)
.with_target("my_target");
let (subscriber, handle) = subscriber::mock()
.new_span(
span.clone()
@ -121,12 +130,17 @@ fn skip() {
.enter(span2.clone())
.exit(span2.clone())
.drop_span(span2)
.new_span(span3.clone())
.enter(span3.clone())
.exit(span3.clone())
.drop_span(span3)
.done()
.run_with_handle();
with_default(subscriber, || {
my_fn(2, UnDebug(0), UnDebug(1));
my_fn(3, UnDebug(0), UnDebug(1));
my_fn2(2, UnDebug(0), UnDebug(1));
});
handle.assert_finished();