rust-cli / env_logger

A logging implementation for `log` which is configured via an environment variable.
https://docs.rs/env_logger
Apache License 2.0
782 stars 124 forks source link

logger crate catches Clion stop signal #305

Closed lioriz1 closed 5 months ago

lioriz1 commented 5 months ago

Passing this issue, here.

I'm using Clion developing in a remote environment. When I'm stoping the process from the clion stop the logs stops but the process not.

fn init_logger() -> Result<(), String> {
    env_logger::Builder::new()
        .format(|buf, record| {
            writeln!(
                buf,
                "{}:{} {} [{}]: {}",
                record.file().unwrap_or("unknown"),
                record.line().unwrap_or(0),
                chrono::Local::now().format("%Y-%m-%d %H:%M:%S.%3f"),
                record.level(),
                record.args()
            )
        })
        .filter(None, LevelFilter::Debug)
        .init();
    Ok(())
}

fn main() -> Result<(), String>  {
    let _ = init_logger();
    info!("Hello, world!");
    for i in 0..10 {
        info!("{}", i);
        // spdlog::info!("{}", i);
        // println!("{}", i);
        thread::sleep(Duration::from_secs(1));
    }
    return Ok(());
}

In this example when I'm stopping the process in the middle the logs will stop but the loop will run to the end, the full 10 seconds and the process will exit successfully.

If I change from log::info! to spdlog::info! or from log::info! to println! or adding .is_test(true) to log init, it works as expected, exits imidietly with fail code.

If I run in regular Clion run on my machine compiler log works fine the same as the other loggers but I would expect it to work the same in my remote environment.

Is there a reason for this behavior? What is the .is_test(true) flag?

epage commented 5 months ago

By "exit immediately", you are referring to a panic from a broken pipe? That is not expected behavior and we try to avoid it (e.g. #221).

println panics on a broken pipe error. It is generally best to use writeln and handle the broken pipe error as works best in your application. For example, a tool like ripgrep might decide that it should exit early with a success exit code on a broken pipe.

.is_test(true) is a hack to take advantage of a hack in std / test. The default test harness, test, uses an unstable hook into std to capture the output from print/println so that it can hide it by default and then only print it along with the test failure. .is_test(true) forces env_logger to go through println so logged messages from a test can be captured with the test.

As this is working as expected, I'm going to go ahead and close this.