-
Notifications
You must be signed in to change notification settings - Fork 13.3k
log: LogRecord #13912
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
log: LogRecord #13912
Conversation
} | ||
|
||
struct DefaultLogger { | ||
handle: LineBufferedWriter<io::stdio::StdWriter>, | ||
} | ||
|
||
struct LevelStr(u32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be public?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be? I just wrote so I could impl fmt::Show, in order to write a str or u32 without allocating a ~str.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like external loggers might find it useful too.
Maybe the log level could just be
pub struct LogLevel {
pub level: u32
}
which implements Show
as a string, but still provides easy access to the internal number. (I guess the field could be private too, and offer a retrieval method.)
(In any case, with or without any of these changes, this should be storing a LogLevel
, not a u32
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh derp, you're right. I changed everything to LogLevel except there.
I'd been thinking of making Level an enum, but that stops people from using
other levels.
On May 2, 2014 7:44 PM, "Huon Wilson" [email protected] wrote:
In src/liblog/lib.rs:
}
struct DefaultLogger {
handle: LineBufferedWriterio::stdio::StdWriter,
}+struct LevelStr(u32);
Seems like external loggers might find it useful too.
Maybe the log level could just be
pub struct LogLevel {
pub level: u32}which implements Show as a string, but still provides easy access to the
internal number. (I guess the field could be private too, and offer a
retrieval method.)(In any case, with or without any of these changes, this should be storing
a LogLevel, not a u32.)—
Reply to this email directly or view it on GitHubhttps://github.com//pull/13912/files#r12254268
.
I did some code size analysis before and after these changes. The test file I was using had 500 invocations of Before this change, there is 0x00134c70 bytes of text. After this change, there was 0x0013f070 bytes of text, a 41984 byte increase, 83 extra bytes per callsite. I made a tweak, causing the code size to increase instead to 0x001365a0, a delta of 6448 bytes, 12 bytes per callsite. It does involve more stuff in the data section, but it's less rarely used, so perhaps it's not all that bad. Could you change the
The LogLocation structure would be statically generated for each invocation of
|
I quite dislike splitting it into 3 arguments like that. The gain is that the |
The The interface of the logger won't change, it will still take just a |
Oh I see, log will take those args and create a LogRecord. I was worried |
@alexcrichton like that? |
None => level.fmt(fmt) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I'm entirely convinced of this new LogLevel
structure. The inner field is private, so it doesn't allow inspecting the value itself, and if it were public, why wrap it in a structure? If it's just used for formatting, it seems like it should be used locally in the implementation of DefaultLogger
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My goals are that in other languages, such as Python, a log record contains the level and the levelname. The level is more useful for filtering, such as if record.level >= log::WARN
. And then the levelname is more useful in formatting. However, since you can specify custom levels that don't have a name, you might need to output just the level number.
So, I need:
- easy
Ord
. Probably against a u32, but maybe it'd be fine to ask people to doif record.level >= LogLevel(20)
- Easy outputting of the name or number. I figured I could implement
fmt::Show
andfmt::Signed
for LogLevel. Show would try to show the name if possible, and Signed would always just show the number. - No need to have both
level
andlevelname
as fields on the LogRecord, since they can be derived when needed.
I also wanted to add fmt::Signed
to LogLevel
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, in that case, you may also want to make sure the field is public via pub LogLevel(pub u32)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fixing up the missing pieces of LogLevel right now... as a special representation of a u32, does it make since to also include FromPrimitive
and ToPrimitive
? I don't fully grasp the use of those traits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd stick with the simpler implementation for now and just implement things like Ord
That looks great, thanks! Just a few things:
|
The logging macros now create a LogRecord, and pass that to the Logger, instead of passing a `level` and `args`. The new signature is: trait Logger { fn log(&mut self, record: &LogRecord); } The LogRecord includes additional values that may be useful to custom loggers, and also allows for further expansion if not values are found useful. DefaultLogger's formatting was taken from Python's default formatting: `LEVEL:from: message` Also included: fmt::Arguments now implement Show, so they can be used to extend format strings. [breaking-change]
Ok, improved LogLevel, adjust commit message for "breaking-changes", and fixed failure in travis. |
The logging macros now create a LogRecord, and pass that to the Logger. This will allow custom loggers to change the formatting, and possible filter on more properties of the log record. DefaultLogger's formatting was taken from Python's default formatting: `LEVEL:from: message` Also included: fmt::Arguments now implement Show, so they can be used to extend format strings. @alexcrichton r?
close rust-lang#13781 The `slow_vector_initialization` lint currently only suggests using the `vec!` macro with size, but it does not suggest removing the `resize` method call. changelog: [`slow_vector_initialization`]: improve `slow_vector_initialization` suggestion
changelog: [`slow_vector_initialization`]: auto-fix when appropriate I made a change for `slow_vector_initialization` lint suggestion to use `vec!` with size and remove the unneeded `resize` (or similar one) call in rust-lang#13912, while only the former one was suggested in the previous implementation. Now, I think this lint can be automatically fixed with no unnecessary code in some cases. I wrote “in some cases” because if there are comments between vector declaration and `resize`, Clippy shouldn't apply auto-fix because the comment may informational.
The logging macros now create a LogRecord, and pass that to the Logger. This will allow custom loggers to change the formatting, and possible filter on more properties of the log record.
DefaultLogger's formatting was taken from Python's default formatting:
LEVEL:from: message
Also included: fmt::Arguments now implement Show, so they can be used to
extend format strings.
@alexcrichton r?