slog icon indicating copy to clipboard operation
slog copied to clipboard

What I would do differently now.

Open dpc opened this issue 5 years ago • 2 comments

https://github.com/slog-rs/slog/tree/v3 me trying out things that I think should have been different.

dpc avatar Aug 27 '18 17:08 dpc

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.

  1. Maybe rebuild everything from the ground up with serde support?
  2. 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 Spans).
    • This also adds additional complexity by switching from macro magic to a recursive decent parser
  3. 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))
  4. Use generics everywhere and avoid dynamic dispatch if at all possible
  5. 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.

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 avatar Aug 28 '18 19:08 Techcable

@Techcable

  1. is part of what I would do differently
  2. would be awesome
  3. 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!

dpc avatar Aug 28 '18 20:08 dpc