Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 531
Yuri Nasyrov Avatar asked Sep 06 '16 14:09

Yuri Nasyrov


1 Answers

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();
}
like image 89
Shepmaster Avatar answered Nov 04 '22 04:11

Shepmaster