multi-logger 0.0.1

Rusty Horde Loggers
use log::{
    self,
    LogRecord,
    LogLevelFilter,
    LogMetadata,
    SetLoggerError
};
use std::io::prelude::*;
use std::fs::{File,OpenOptions};
use std::io::BufWriter;
use std::ops::DerefMut;
use std::path::PathBuf;
use std::sync::RwLock;
use time;

pub struct FileLogger {
    rwlck: RwLock<BufWriter<File>>
}

impl FileLogger {
    pub fn new(path: PathBuf) -> 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))
        }
    }
}

impl log::Log for FileLogger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            match self.rwlck.write() {
                Ok(ref mut w) => {
                    let mut bw = w.deref_mut();
                    let now = time::now();
                    bw.write_fmt(format_args!("{} {:5} {:4} -- {}: {}\n",
                                              now.rfc3339(),
                                              record.level(),
                                              record.location().line(),
                                              record.location().module_path(),
                                              record.args()))
                        .and(bw.flush()).unwrap();
                },
                Err(e)        => {
                    println!("Unable to acquire write lock! {:?}", e);
                },
            }
        }
    }
}

pub fn init_file_logger(level: LogLevelFilter,
                        path: PathBuf) -> Result<(), SetLoggerError> {
    log::set_logger(|max_log_level| {
        max_log_level.set(level);
        Box::new(FileLogger::new(path))
    })
}