2016-09-06 42 views
7

Próbuję użyć skrzynki z logami i samemu wdrożyć rejestrator. Nazywam to mylog.Dlaczego drop nie jest wymagany do wdrożenia programu rejestrującego?

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) 
    }) 
} 

I main.rs:

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

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

Drop nigdy nie zadzwonił i nie rozumiem dlaczego.

Odpowiedz

7

Implementacja rejestratora jest przekazywana do biblioteki rejestrowania i is effectively leaked. Dzięki temu implementacja może działać w trybie tak, jakby ma okres istnienia , umożliwiając jej używanie w wielu miejscach.

Jeśli naprawdę potrzebujesz, to można wyłączyć rejestrator na końcu programu:

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

Uwaga: Byłem ciekaw wątku bezpieczeństwa niniejszego zaproszenia więc poszedł patrząc na nią; z tego co rozumiem, implementacja utrzymuje licznik tego, ile wątków jest aktualnie rejestrowanych i "zablokuje" w wywołaniu 'shutdown_logger' dopóki wszystkie nie zostaną zakończone. –

+0

@ MatthieuM. Tak, byłem zaskoczony implementacją transmutacji i bazowej atomistyki. – Shepmaster

+0

To pomaga, jeśli ja to nazywam. Ale potrzebuję złapać, gdy program zakończy się z błędem lub zabity. Czy potrzebuję użyć paniki catcher [link] (https://github.com/sfackler/rust-log-panics/blob/master/src/lib.rs)? –