console-rs / indicatif

A command line progress reporting library for Rust
MIT License
4.22k stars 238 forks source link

using indicatif and the log crate #566

Closed djugei closed 11 months ago

djugei commented 11 months ago

This is not an issue but instructions on how you can log messages and have a progress bar at the same time. its an issue that comes up sometimes: https://github.com/console-rs/indicatif/issues/366 https://github.com/console-rs/indicatif/issues/92 https://github.com/console-rs/indicatif/issues/474 https://github.com/console-rs/indicatif/issues/27 possibly https://github.com/console-rs/indicatif/issues/474

You create a global MultiProgress, and then you just need to make your logging implementation, in this example env_logger use that (or rather its println function) as write target. to do so we utilize the pipe crate, but it would also be possible to use a ring buffer or something else:

let (read, write) = pipe::pipe();
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
    .target(env_logger::Target::Pipe(Box::new(write)))
    .init();

let multi = MultiProgress::new();

{
    let m = multi.clone();
    std::thread::spawn(move || {
        let br = std::io::BufReader::new(read);
        for line in br.lines() {
            let line = line.unwrap();
            m.println(&line);
        }
    });
}

then you simply add all your progress bars to the gobal multi and things just work.

i will probably turn this into an example soon. it should be somewhat simple to actually have MultiProgress (or a wrapper of it) to implement the Log trait. i might send a pr for that in a week valve time.

djugei commented 11 months ago

probably better served by https://github.com/console-rs/indicatif/pull/570