2016-09-06 2 views
7

나는 로그 상자를 사용하고 로거를 직접 구현하려고한다. 나는 그것을 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) 
    }) 
} 

그리고 main.rs에서

:

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

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

Drop가 호출되지 않습니다 나는 이유를 이해하지 않습니다.

답변

7

로거 구현은 로깅 라이브러리에 제공되고 is effectively leaked입니다. 따라서 의 구현이 인 것처럼 활성화되어 'static의 유효 기간을 갖기 때문에 여러 위치에서 사용할 수 있습니다.

당신이 정말로 그것을 필요한 경우,이 프로그램의 끝에서 로거를 종료 할 수 있습니다 :

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

참고 :이 호출 그래서를 조사했습니다의 스레드 안전성에 대한 호기심이었다; 내가 구현 한 것으로부터 현재 얼마나 많은 쓰레드가 로깅되고 있는지를 유지하고, 모든 것이 끝날 때까지'shutdown_logger' 호출에서 "차단"할 것입니다. –

+0

@MatthieuM. 예, 나는 변환과 기본 원자학으로 구현에 놀랐습니다. – Shepmaster

+0

내가 직접 호출하면 도움이됩니다. 하지만 프로그램이 오류로 끝나거나 죽을 때를 잡아야합니다. 아니면 공황 포수 (link : https://github.com/sfackler/rust-log-panics/blob/master/src/lib.rs)를 사용해야합니까? –

관련 문제