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

Introduce a formatter sigil for "alternate" Display #1311

Open
thomaseizinger opened this issue Mar 18, 2021 · 4 comments
Open

Introduce a formatter sigil for "alternate" Display #1311

thomaseizinger opened this issue Mar 18, 2021 · 4 comments

Comments

@thomaseizinger
Copy link
Contributor

thomaseizinger commented Mar 18, 2021

Feature Request

Motivation

anyhow provides a formatting of the whole error chain through the alternate selector {:#}: https://docs.rs/anyhow/1.0.38/anyhow/struct.Error.html#display-representations

It would be nice to make use of this within tracing events in a concise way.

Proposal

Add a formatter sigil (possibly #) to tracing that allows to print values using their alternate Display implementation.

For example:

let error = anyhow!("Oh noes!").context("Something went horribly wrong!");

tracing::error!(#error, "What a mess")

Would print as:

ERROR What a mess error=Something went horribly wrong!: Oh noes!

Alternative

One can convert an anyhow error into a std-error. If reporting std-errors were to be made more ergonomic AND tracing provides a way of printing all causes of std-errors, then this feature is not needed. That being said, triggering the alternative Display impl is not specific to anyhow and might be useful in general.

@hawkw
Copy link
Member

hawkw commented Mar 18, 2021

I'm open to adding an alt-mode sigil to format specifiers. I imagine what we would want to do is add it as a modifier for both the Display and Debug sigils, so you can write ?# as well as %#.

Implementing alt mode as a sigil would add a lot of new complexity to the macros, though, which is not ideal. I think it might be worth trying to design a more general way to include any arbitrary format specifiers (such as, for example, format an integer in hexadecimal) without having to write field = format_args!("{:x}", hex_number) or similar, which is quite verbose. I'm not sure what a syntax for arbitrary format specifiers would look like, off the top of my head, but I'm open to suggestions!

@thomaseizinger
Copy link
Contributor Author

thomaseizinger commented Mar 22, 2021

I'm not sure what a syntax for arbitrary format specifiers would look like, off the top of my head, but I'm open to suggestions!

What comes to my mind is a similar syntax as here: https://docs.rs/thiserror/1.0.24/thiserror/#details

For example:

let id = Uuid::new_v4();

tracing::debug!({id}, "New ID generated"); // {} prints as Display
tracing::debug!({id:?}, "New ID generated"); // {:?} prints as Debug
tracing::debug!({id:#}, "New ID generated"); // {:?} prints as Display alternate
// etc

We could still retain a special case of:

tracing::debug!(id, "New ID generated");

For using the regular Display impl which I assume is going to be quite common.

@let4be
Copy link

let4be commented May 11, 2021

Also need to support this in #instrument macro as it can be made to print errors as well...

@lilyball
Copy link
Contributor

lilyball commented Nov 4, 2021

An arbitrary format syntax would be great, but I think "alternate mode" is the most important and it would be perfectly okay if we simply supported that and required format_args!() for anything more complicated.

The lack of support for # is something that I keep running into, especially when trying to port code from slog to tracing (as slog supports the # modifier).

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

4 participants