Yuri Nasyrov
Yuri Nasyrov

Reputation: 73

Why is drop not called for a logger implementation?

I'm trying to use the log crate and implement a logger myself. I call it mylog.

extern crate log;
use log::*;

struct Mylog;

impl log::Log for Mylog {
    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= LogLevel::Info
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("hello log");
        }
    }
}
impl Drop for Mylog {
    fn drop(&mut self) {
        println!("dropped"); // This is never called, why?
    }
}
pub fn init() -> Result<(), SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(LogLevelFilter::Info);
        Box::new(Mylog)
    })
}

And in main.rs:

extern crate mylog;
#[macro_use] extern crate log;

fn main() {
    mylog::init().unwrap();
    info!("My info message");
}

Drop is never called and I don't understand why.

Upvotes: 7

Views: 256

Answers (1)

Shepmaster
Shepmaster

Reputation: 431479

The logger implementation is given to the logging library and is effectively leaked. This allows the implementation to act as if it has the 'static lifetime, letting it be used in many places.

If you really need it, you can shut down the logger at the end of the program:

fn main() {
    mylog::init().unwrap();
    info!("My info message");
    log::shutdown_logger();
}

Upvotes: 7

Related Questions