libmultilog 0.1.0

Various logging implementations in Rust
Documentation
//! File Logger
use log::{self, LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};
use regex::Regex;
use std::collections::HashMap;
use std::io::prelude::*;
use std::fs::{File, OpenOptions};
use std::io::BufWriter;
use std::ops::DerefMut;
use std::path::PathBuf;
use std::sync::{Arc, Mutex, RwLock};

/// File Logging Function
pub type LogFunction = fn(&LogRecord, &mut BufWriter<File>);

/// File Logger struct
pub struct FileLogger {
    rwlck: RwLock<BufWriter<File>>,
    filters: HashMap<usize, Regex>,
    outputfn: Arc<Mutex<LogFunction>>,
}

impl FileLogger {
    /// Create a new FileLogger.
    pub fn new(path: PathBuf, ofn: LogFunction) -> FileLogger {
        let mut opts = OpenOptions::new();
        opts.create(true);
        opts.write(true);
        opts.append(true);

        let file = match opts.open(&path) {
            Ok(f) => f,
            Err(e) => panic!("Unable to use file for logging! {}", e),
        };

        FileLogger {
            rwlck: RwLock::new(BufWriter::new(file)),
            filters: HashMap::new(),
            outputfn: Arc::new(Mutex::new(ofn)),
        }
    }

    /// Add a filter to the file logger.
    pub fn add_filter(&mut self, lvl: LogLevel, r: Regex) -> &mut FileLogger {
        self.filters.insert(lvl as usize, r);
        self
    }
}

impl log::Log for FileLogger {
    fn enabled(&self, meta: &LogMetadata) -> bool {
        match self.filters.get(&(meta.level() as usize)) {
            Some(re) => !re.is_match(meta.target()),
            None => true,
        }
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            match self.rwlck.write() {
                Ok(ref mut w) => {
                    match self.outputfn.lock() {
                        Ok(ref mut f) => {
                            f(record, w.deref_mut());
                        }
                        Err(e) => {
                            println!("Unable to acquire lock! {}", e);
                        }
                    };
                }
                Err(e) => {
                    println!("Unable to acquire write lock! {:?}", e);
                }
            }
        }
    }
}

/// Initialize the file logger.
pub fn init_file_logger(level: LogLevelFilter, logger: FileLogger) -> Result<(), SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(level);
        Box::new(logger)
    })
}