Drakulix / simplelog.rs

Simple Logging Facility for Rust
https://docs.rs/simplelog/
Apache License 2.0
423 stars 71 forks source link

Make try_log public so that custom loggers can use it #104

Open Boscop opened 2 years ago

Boscop commented 2 years ago

My use case that requires this change is: From my DLL plugin I want to log to a file but also to the host, by sending it strings (one per log record). I need to log each line separately to the host, but Write doesn't let me know when each record starts/ends. So I need to log to a String (actually Cursor<Vec<u8>>, then str::from_utf8, then send the String to the host) and I need to be able to call try_log for that.

Boscop commented 1 year ago

I'm not sure what kind of doc to add. In my use case, my DLL logger has to call try_log and then logs to the host via host_log. (I need to log each line separately to the host, but Write wouldn't let me know when each record starts/ends.)

Like this:

pub struct HostLogger {
    level: LevelFilter,
    config: Config,
}

impl HostLogger {
    pub fn new(log_level: LevelFilter, config: Config) -> Box<HostLogger> {
        Box::new(HostLogger { level: log_level, config })
    }
}

impl Log for HostLogger {
    fn enabled(&self, metadata: &Metadata<'_>) -> bool {
        metadata.level() <= self.level
    }

    fn log(&self, record: &Record<'_>) {
        if self.enabled(record.metadata()) {
            let mut s = Vec::new();
            let _ = try_log(&self.config, record, &mut Cursor::new(&mut s));
            let s = std::str::from_utf8(&s).expect("utf8").trim();
            host_log(s);
        }
    }

    fn flush(&self) {}
}

impl SharedLogger for HostLogger {
    fn level(&self) -> LevelFilter {
        self.level
    }

    fn config(&self) -> Option<&Config> {
        Some(&self.config)
    }

    fn as_log(self: Box<Self>) -> Box<dyn Log> {
        Box::new(*self)
    }
}