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

Make primary writers public? #47

Closed
pscott opened this issue Jun 12, 2020 · 5 comments
Closed

Make primary writers public? #47

pscott opened this issue Jun 12, 2020 · 5 comments

Comments

@pscott
Copy link

pscott commented Jun 12, 2020

I'm trying to log things to a file, stderr, and stdout at the same time.

To do that I must create a new writer for Stdout which I've done this way:

struct StdoutWriter {
    format: FormatFunction,
    log_level: log::LevelFilter
}

impl StdoutWriter {
    fn new(format: FormatFunction, log_level: LevelFilter) -> Self {
        StdoutWriter { format, log_level}
    }
}

impl LogWriter for StdoutWriter {
    #[inline]
    fn write(&self, now: &mut DeferredNow, record: &Record) -> std::io::Result<()> {
        (self.format)(&mut std::io::stdout(), now, record)
    }

    fn flush(&self) -> std::io::Result<()> {
        std::io::stdout().flush()
    }

    fn max_log_level(&self) -> log::LevelFilter {
        self.log_level
    }
}

However, I was wondering if flexi_logger couldn't expose the StdoutWriter that it already uses internally (as a Primary Writer), to make that easier.
Or maybe I'm missing something :)

Thanks!

@pscott
Copy link
Author

pscott commented Jun 12, 2020

To make sure we avoid the XY problem, I'm trying to build a logger that works like this:

let log_file: Option<PathBuf>; // path to directory
let stderr_isatty = atty::is(atty::Stream::Stderr); // whether stderr is attached to a terminal or not
match (log_file, isatty) {
  (None, true) => , // Only log to stderr
  (None, false) => , // Log to stderr, and duplicate >= INFO to stdout
  (Some(dir), true) => ,// Log to file, duplicate ALL to stderr, nothing to stdout
  (Some(dir), false) => , // Log to file, duplicate to stderr, and duplicate >= INFO to stdout
}

edit: just noticed that duplication does not occur if log_target is Stderr or Stdout ^^'

@emabee
Copy link
Owner

emabee commented Jun 18, 2020

In branch issue-47 I added a builder option 'Logger::duplicate_to_stdout()'.

With this, you could use

// Only log to stderr
        .log_target(LogTarget::StdErr)

// Log to stderr, and duplicate >= INFO to stdout
        .log_target(LogTarget::DevNull)  // only pretends to log
        .duplicate_to_stderr(Duplicate::All)
        .duplicate_to_stdout(Duplicate::Info)

// Log to file, duplicate ALL to stderr, nothing to stdout
        .log_target(LogTarget::File) 
        .duplicate_to_stderr(Duplicate::All)

// Log to file, duplicate to stderr, and duplicate >= INFO to stdout
        .log_target(LogTarget::File) 
        .duplicate_to_stderr(Duplicate::All)
        .duplicate_to_stdout(Duplicate::Info)

What do you think?

@pscott
Copy link
Author

pscott commented Jun 20, 2020

Yup sounds good!
I would never have thought about using LogTarget::DevNull to "pretend" to log in order to be able to duplicate. It might be worth mentioning it in the docs somewhere (my two cents! :)).

Thank you so much for your help!

@emabee
Copy link
Owner

emabee commented Jun 20, 2020

Implemented with version 0.15.5.

@emabee emabee closed this as completed Jun 20, 2020
@pscott
Copy link
Author

pscott commented Jun 21, 2020

@emabee Getting back to this issue, I think I'm missing something like format_for_stdout() to be able to log with colors to stdout, while keeping LogTarget::Stderr and LogTarget::File without colors. Should I try submitting a PR for this one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants