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

An RFC for inline expression and value logging #317

Open
wants to merge 6 commits into
base: master
from

Conversation

Projects
None yet
3 participants
@dekellum
Copy link
Contributor

dekellum commented Jan 30, 2019

Add support to log for inline expression and value logging, as a superset of the dbg! macro recently added to rust std.

Rendered

Implementation PR: #316

@KodrAus

This comment has been minimized.

Copy link
Contributor

KodrAus commented Jan 30, 2019

Thanks for putting this together @dekellum! I'll have a proper read shortly, but I've posted a link to the subreddit that points back here, just in case we get any comments there.

@KodrAus KodrAus added the rfc label Jan 30, 2019

partially mitigated by documented such an extension crate in the log
README and/or top-level library rustdoc.

* The community effort to maintain such a separate library with

This comment has been minimized.

@KodrAus

KodrAus Jan 30, 2019

Contributor

On the other hand, supporting this in log becomes a similar burden for folks working on log itself, but the expected parity between log and logv style macros when they're both in log becomes even tighter.

This comment has been minimized.

@dekellum

dekellum Jan 31, 2019

Contributor

That's entirely fair, but note also that the implementation of logv! is currently pretty minimal and ultimately funnels into log!. The other -v macros (debugv!, etc.) are one line rules.

This comment has been minimized.

@KodrAus

KodrAus Feb 3, 2019

Contributor

I think the issue is more tied to the amount of context than to the amount of code to support. It just means it's another feature to keep in mind when evolving the library.

I find your argument about the duplicated macros we already have for info, warn etc pretty convincing though. It's not like we don't already have a suite of similar macros.

formatted to a temporary `fmt::Arguments` before formatting to the
final message.

## Release this as a separate crate, not in `log`

This comment has been minimized.

@KodrAus

KodrAus Jan 30, 2019

Contributor

This is the big question for me. Are users of the log crate going to get enough value out of logv to warrant building and supporting a parallel API?

Your point about debug, info, warn etc already being effectively parallel APIs is reasonable though.

tracev!("{} = {:x}", i); // hexadecimal format value
tracev!("{} = {:#?}", i); // use pretty, multi-line format
let rem = infov!("{1:?} remaining ({0})", deadline - Instance::now());

This comment has been minimized.

@KodrAus

KodrAus Jan 30, 2019

Contributor

I quite like how this has turned out 👍

* The community effort to maintain such a separate library with
compatibility to the `log` crate, as it evolves. For example, the
_-v_ macros will likely need to be adapted, when structured logging
is implemented ([log RFC 296]).

This comment has been minimized.

@KodrAus

KodrAus Jan 30, 2019

Contributor

How this interacts with structured logging will be interesting. I think we should be able to decorate a Record with at least the stringified expression as a structured value, and use the Debug representation of the value if the user hasn't supplied an explicit format function to logv.

This comment has been minimized.

@dekellum

dekellum Jan 30, 2019

Contributor

This is, in addition to allowing the same sort of structured key+values, at the end of the -v macro arguments? Here I think you are providing evidence in favor of including this feature in log itself, so these features can be more closely integrated as appropriate.

This comment has been minimized.

@KodrAus

KodrAus Feb 3, 2019

Contributor

Yeh, I was running through the exercise of whether we'd be worse off for adding this feature and then having to introduce structured logging without breakage to it later, which I think we'll be able to do just fine. So no issues there.

## Multiple expression support

[RFC 2173] included multiple-expression support for `std::dbg!` but
was closed, at least in part due to perceived complexity with multiple

This comment has been minimized.

@Centril

Centril Jan 30, 2019

I don't think this is borne out; dbg!(a, b, c) is desired:

And moreover I don't think it was the reason 2173 was closed:

The main issue was instead that the original macro permitted labels, took into account debug/release mode and environment variables.

If all you want to do is extend the dbg! macro to support multiple arguments that's quite exceedingly simple (playground):

macro_rules! dbg {
    () => { dbg!(()) };
    ($val:expr) => {
        match $val {
            tmp => {
                eprintln!("[{}:{}] {} = {:#?}",
                    file!(), line!(), stringify!($val), &tmp);
                tmp
            }
        }
    };
    ($($val:expr),+ $(,)?) => { ($(dbg!($val)),+,) };
}

fn main() {
    let _: () = dbg!();

    let _: (u8,) = dbg!(1,);

    let _: u8 = dbg!(1);

    let _: (u8, u8) = dbg!(1, 2);

    let _: (u8, u8) = dbg!(3, 4,);
}

As you can see, to support multiple arguments a single line was required, and one for supporting dbg!().

What the original macro did wrt. multiple arguments, and which contributed significantly to complexity, was to lock stderr only once so as to improve performance, but that might not actually be important so the code above works if we are more concerned about complexity than performance.

Why do I bring all this up? Well... I have a bit of a concern that if log goes for a format string rather than multiple arguments (which I think is more useful for dbg!'s quick debugging purpose), then it will be somewhat expected that dbg! also does this as opposed to adding multi argument support. My concern is lessened by the fact that you're not calling the macro dbg!, but I would like to be disabused of this concern entirely such that the standard library is free to go in either direction.

This comment has been minimized.

@dekellum

dekellum Jan 30, 2019

Contributor

Thanks @Centril. I will refine this alternative subsection to (a) presume less about why RFC 2173 was superseded; (b) point out that both multiple arguments and a custom format string are at least somewhat at odds, and (c) note that the following still works, as currently designed, by explicitly passing a tuple:

let i = 16;
assert_eq!(debugv!((i/4, i/8)), (4, 2));
assert_eq!(debugv!("{} = {:?}", (i/4, i/8)), (4, 2));

Regarding your multiple argument example macro: It would be surprising and undesirable in a log context, I think, to write more than one log record for a single -v macro invocation. To "lock stderr only once" sounds like a closely related goal.

This comment has been minimized.

@Centril

Centril Jan 30, 2019

Thanks @dekellum; I agree with you about the distinction between logging and debugging wrt. the usefulness of multiple arguments; dbg!(a, b, c) seems more useful than debugv!(a, b, c). Fwiw, I think this RFC is a nice addition. :)

This comment has been minimized.

@dekellum

dekellum Jan 31, 2019

Contributor

Updated this alternatives subsection, per above, and with further elaboration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment