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

Avoid allocation of String during formatting. #19

Merged
merged 1 commit into from
Aug 28, 2017
Merged

Avoid allocation of String during formatting. #19

merged 1 commit into from
Aug 28, 2017

Conversation

mjkillough
Copy link
Contributor

The format function is now passed a &mut std::io::Write trait object
and is responsible for outputting the formatted message to it. Format
functions can take care (by using the std::fmt macros) to avoid heap
allocations during formatting/outputting of log messages, and the
default format function takes advantage of this.

Alternatives considered:

  • Have the format function return a fmt::Arguments (from a call to
    format_args!(). Unfortunately I couldn't find a way to make this
    work with the lifetime parameter on fmt::Arguments.
  • Give the format function something like fern's FormatCallback:
    https://docs.rs/fern/0.4.2/fern/struct.FormatCallback.html rather
    than giving it the &mut Write. This would be more future proof, but
    I worry it introduces unnecessary abstraction into env_logger,
    which generally tries to keep things simple.

... but I don't think either of those are better.

Some open questions:

  • Is referring to it as a 'format function' still appropriate? Should
    Builder::format() be renamed?
  • Should we be backwards-compatible with current env_logger by allowing
    people to give a Fn(&Record) -> String still? (Should we make
    upgrades easier or encourage people to rethink their format functions
    and whether they heap allocate?)

Fixes #3.

The format function is now passed a `&mut std::io::Write` trait object
and is responsible for outputting the formatted message to it. Format
functions can take care (by using the `std::fmt` macros) to avoid heap
allocations during formatting/outputting of log messages, and the
default format function takes advantage of this.

Alternatives considered:

 - Have the format function return a `fmt::Arguments` (from a call to
   `format_args!()`. Unfortunately I couldn't find a way to make this
   work with the lifetime parameter on `fmt::Arguments`.
 - Give the format function something like `fern`'s `FormatCallback`:
   https://docs.rs/fern/0.4.2/fern/struct.FormatCallback.html rather
   than giving it the `&mut Write`. This would be more future proof, but
   I worry it introduces unnecessary abstraction into `env_logger`,
   which generally tries to keep things simple.

... but I don't think either of those are better.

Some open questions:

 - Is referring to it as a 'format function' still appropriate? Should
   `Builder::format()` be renamed?
 - Should we be backwards-compatible with current env_logger by allowing
   people to give a `Fn(&Record) -> String` still? (Should we make
   upgrades easier or encourage people to rethink their format functions
   and whether they heap allocate?)

Fixes #3.
@mjkillough
Copy link
Contributor Author

If it's desirable to add color support (#2) then perhaps we should pass some kind of new Output type to the format functions (rather than std::io::Write). This would allow us to add an Output::supports_ansi_colors() method. Formatters could use this in order to decide whether to use ansi_term to output colored logs on ANSI terminals, or to output non-colored logs for non-ANSI terminals.

We could also build the machinery for outputting colors in a cross-platform way into the Output type, but that seems like massive scope creep. :)

@sebasmagri
Copy link
Collaborator

@mjkillough color support is not in the current scope but something we could look at in the future. For now I think this is completely fine.

Thanks!

@tailhook
Copy link
Contributor

Hi,

Is there any actual need for this PR? The problem is that unbuffered writes of logs aren't very good if you have multiple threads or even multiple processes. I.e you will get a mess of different pieces of different log messages. Previous implementation added \n afterwards and even that was a problem. So I think the good idea is to make better buffering as added in rust-lang/log#219 rather than remove buffering.

@KodrAus
Copy link
Collaborator

KodrAus commented Sep 18, 2017

I think this is a valid point. Thanks for following this up @tailhook! I'll open up an issue shortly to discuss sinks so we can iterate towards an implementation that satisfies all the things we expect from them.

epage added a commit to epage/env_logger that referenced this pull request Apr 17, 2024
chore(ci): Ensure CI job always runs
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

Successfully merging this pull request may close these issues.

4 participants