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

More Fine-Grained Verbosity Settings #229

Closed
cramertj opened this issue Sep 29, 2017 · 20 comments
Closed

More Fine-Grained Verbosity Settings #229

cramertj opened this issue Sep 29, 2017 · 20 comments

Comments

@cramertj
Copy link
Member

cramertj commented Sep 29, 2017

Currently, log levels are represented by a LogLevel enum:

pub enum LogLevel {
    Error,
    Warn,
    Info,
    Debug,
    Trace,
}

In my experience, five log levels is enough for most use cases. However, I don't see a reason why log should limit the user to this finite set. Consider adding a custom-verbosity variant that includes an integer specifying the log level:

pub enum LogLevel {
    Error,
    Warn,
    Info,
    Debug,
    Trace,
    CustomVerbosity(u8), // bikeshed away on the name :)
}

Apologies if I missed an existing issue or conversation around this!

@sfackler
Copy link
Member

What would CustomVerbosity(4) mean, and how would it compare to, say Info?

@cramertj
Copy link
Member Author

cramertj commented Sep 29, 2017

I'm not quite sure of the best semantics. It seems like CustomVerbosity is really just a more fine-grained Info. Perhaps rank them something like this: Trace > Debug > Info > CustomInfo(255) > CustomInfo(0) > Warn > Error.

@sfackler
Copy link
Member

sfackler commented Oct 1, 2017

That ordering doesn't seem super obvious to me at least. Do any other logging frameworks in other languages do this kind of thing? I'm not familiar with any that do personally.

Filtering is traditionally done based off of the modules you care about, not turning on log levels 57 and up. Trying to maintain a reasonable ordering of log verbosity/priority with 261 levels seems like it would be pretty hard in a large codebase.

@cramertj
Copy link
Member Author

cramertj commented Oct 1, 2017

Google glog lets you set a custom level using V (for verbosity).

@cramertj
Copy link
Member Author

cramertj commented Oct 1, 2017

In practice, it's usually less that you have 57 levels, and more that you have three or four different levels of "Info"-type logs.

@sfackler
Copy link
Member

sfackler commented Oct 1, 2017

Glog's setup seems a bit different than this, though. The verbosity seems orthogonal to the level there, right?

@sfackler
Copy link
Member

sfackler commented Oct 1, 2017

Oh nevermind, I misread that.

@sfackler
Copy link
Member

sfackler commented Oct 1, 2017

In glog's case, there are no verbosity levels above INFO, which is where the V stuff comes in. Here, we have Debug and Trace. If anything, it seems like the V equivalent in this library would be even more verbose than trace, right?

@cramertj
Copy link
Member Author

cramertj commented Oct 1, 2017

Yeah, I suppose you could also organize it that way.

@sfackler
Copy link
Member

sfackler commented Oct 1, 2017

The way this would work is probably something like this:

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Level(u8);

impl Level {
    pub const ERROR: Level = Level(1);
    pub const WARN: Level = Level(2);
    pub const INFO: Level = Level(3);
    pub const DEBUG: Level = Level(4);
    pub const TRACE: Level = Level(5);

    pub fn custom(level: u8) -> Level {
        assert!(level > 5);
        Level(level)
    }
}

I'm not totally sold that this is a good idea, though. Logging libraries need to decide how they want to display and consume custom levels. Library authors now need to go from figuring out which of 5 levels is appropriate for an individual message to which of 255 is appropriate.

@cramertj
Copy link
Member Author

cramertj commented Oct 2, 2017

My expectation would be that library authors would create their own level constants, which they could use to give more specific semantic meaning to the levels.

@sfackler
Copy link
Member

sfackler commented Oct 2, 2017

But how many new levels will people actually need in practice? It's already super uncommon in my experience to ever turn on trace-level logging, and that only needs to happen when something really weird is going on. For example, Hyper's trace logging helped diagnose a protocol bug since it dumped a ton of information about its state and the data coming in off the wire.

Do you have an example of a library that needs even more levels of verbosity than what trace would give you?

@cramertj
Copy link
Member Author

cramertj commented Oct 5, 2017

@sfackler Not that I can recall, no.

@sfackler
Copy link
Member

In the absence of a more concrete use case, I think we'll keep things as-is for the 0.4 release.

@cramertj
Copy link
Member Author

Okay! That seems fine to me. I still think it would be interesting to explore a design like the one you suggested above, since it seems more extensible to me, and I don't see any real downsides. However, I agree with you that it does seem like a bit of a solution in need of a problem. 😄

@sfackler
Copy link
Member

There is a real downside for that approach - you can no longer exhaustively match on the level.

@cramertj
Copy link
Member Author

cramertj commented Oct 13, 2017

@sfackler Yeah, that seems good to me-- it seems like what you'd usually want is to work with things above or below a certain level, not implement specific behaviors for each individual level. I could be wrong, though.

@sfackler
Copy link
Member

You need specific behavior if you e.g. want to translate a log level to a name.

@cramertj
Copy link
Member Author

Sure, but you could just match on the cases that you know, and set the rest to "CUSTOM" or similar.

@cramertj
Copy link
Member Author

It might even be worthwhile to let crates specify their own translators for a given target, so that their custom levels show up correctly.

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