slog
slog copied to clipboard
What I would do differently now.
https://github.com/slog-rs/slog/tree/v3 me trying out things that I think should have been different.
Generally logging latency always seems to be way too high for me to use in super-hot code like my VM's interpreter loop. I always have to hide it behind a special flag since all the serialization is by far the slowest part of my interpreter by a couple orders of magnitude. I'm not even sure slog-async
would work since the interpreter generates megabytes of data just by running for ~5 minutes (~3 seconds if logging is disabled).
Here are some crazy things we might be able to change to fix these performance problems.
- Maybe rebuild everything from the ground up with serde support?
- Reimplement
log!
using a functionlike procedural-macro- This would give us and allow us to give beautiful error messages if the error
- Main downside of this approach is functionlike procedural macros only work on nightly (especially if you want to use
Span
s). - This also adds additional complexity by switching from macro magic to a recursive decent parser
- Use a procedural derive to generate a
struct
to hold logging messages, allowing serde to use sepcialized serialization code for each log message- One of the nicest things about this aproach is you could use the same structure for serialization both, as long as you
#[derive(SlogValue)]
for the structure - For convenience, we'd probably also allow you to implicitly define structs as well using the procedural macro (
log!(logger, "Message Name"; first => "hello", second => variable)
)
- One of the nicest things about this aproach is you could use the same structure for serialization both, as long as you
- Use generics everywhere and avoid dynamic dispatch if at all possible
- Since we're using generics and want to avoid dynamic dispatch, we would need to write directly to formatters using instead of
std::fmt
if at all possible (like in itoa)- We can fallback to
std::fmt
if a type , but the main point is we avoid dynamic dispatch and overhead for formatting simple types like integers and strings.
- We can fallback to
I've considered writing my own binlogger
crate that uses bincode
serialization and makes all these crazy features available under an extension trait.
From what I've played around with it seems possible, although I have no idea if anything like it would be a good idea in slog v3.
@Techcable
- is part of what I would do differently
- would be awesome
- Has a problem that it makes
Logger
paramterized which spreads over everything. However you can avoid it: https://docs.rs/slog/2.3.3/slog/struct.Logger.html#method.root_typed . Anyway - dynamic dispatch is already being avoided, so it shouldn't be much of problem. Eg. the values get monomorphised, etc. Other than that you would have to be more specific, and then we can judge case by case what could be done about it.
Make sure you've seen: https://github.com/slog-rs/slog/wiki/Bench-log . Async logging is quite fast, and the important part is that owned values are Arced, so sending them over to another thread is quite fast.
Rust team is working on getting log to 1.0 and some features/strenghts of slog are an explicit goal to port over, so I'd advise to follow the discussion on their github issue, and give feedback there.
Thanks for your comment!