Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support pretty-printing fields tracing::instrument (i.e., {:#?} instead of {:?}). #1752

Open
BGR360 opened this issue Nov 29, 2021 · 1 comment

Comments

@BGR360
Copy link

BGR360 commented Nov 29, 2021

Feature Request

My request is that tracing::instrument supports using the pretty-print debug specifier (i.e., {:#?}) to print fields instead of the regular debug specifier (i.e.,{:?}).

Related to / possibly overlapping with:

Crates

tracing-attributes

Motivation

I use tracing::instrument liberally when hacking on the Rust compiler. Oftentimes, the logs get really hard to read when a function has many parameters and each parameter has many fields and nested structs. I very frequently find myself wanting the ability to pretty-print fields so I can more easily see what's going on.

Proposal

No strong feelings on exactly how it should work. Here's one idea:

Two new options, pretty and pretty_all:

#[tracing::instrument(skip(self), pretty(bing, bang))]
fn foo(self, bing: BigNestedStruct, bong: u32, bang: BigNestedStruct) {}

#[tracing::instrument(pretty_all)]
fn bar(sneeb: BigNestedStruct, snob: BigNestedStruct) {}

Perhaps this could be generalized so that users could write their own field formatter and easily inject that into the instrument invocation:

#[tracing::instrument(fmt = tracing::field::debug)]  // default behavior
fn foo(bing: &str, bong: u32) {}

#[tracing::instrument(fmt = path::to::my_formatter)]
fn bar(sneeb: BigNestedStruct, snob: BigNestedStruct) {}

EDIT: I think this is precisely the idea of #1312

Alternatives

Quoting from #1089 (comment):

Note, though, that you can also do this by skipping all the automatically-generated fields, and adding custom fields using your own wrapper type. For example:

#[tracing::instrument(
    skip(foo, bar),
    fields(foo = ?my_wrapper(foo), bar = ?my_wrapper(bar))
)]
fn my_function(foo: Foo, bar: Bar) {
   /// ...
}

Too much work :P

@vladh
Copy link

vladh commented Jul 2, 2024

Something like this is already supported, but it's extremely non-obvious and it took me around an hour to find. The format using # is called the alternate format, and you can tell tracing_subscriber to use it:

use tracing_subscriber::field::MakeExt;

tracing_subscriber::fmt()
    .map_fmt_fields(|f| f.debug_alt())
    .init();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants