I am trying to create a simple file logger using the log facade, but I feel like I dug myself into a hole and can not find the correct way to get out.
I want the logger to hold an handle on the file it is writing too.
However, to write to the file, I should be able to modify the Option, but the log Trait is using a fn log(&self, record: &LogRecord) and not a fn log(&mut self, ...)
So I feel like my approach is wrong, what would be a better way ?
extern crate log;
use std::error::error;
use std::fs::file;
use std::path::path;
use std::io::write;
use log::{logrecord, loglevel, loglevelfilter, setloggererror, logmetadata};
pub struct simplelogger {
logfile: option<file>,
}
impl log::log for simplelogger {
fn enabled(&self, metadata: &logmetadata) -> bool {
metadata.level() <= loglevel::info
}
fn log(&self, record: &logrecord) {
if self.enabled(record.metadata()) {
// println!("{} - {}", record.level(), record.args());
let mut buffer = vec::new();
write!(&mut buffer, "{} - {}", record.level(), record.args());
match self.logfile {
some( file) => { //does not work because should be a ref mut
match file.write(buffer.as_slice()) {
err(why) => panic!("couldn't write: {}", error::description(&why)),
ok(_) => (),
}
}
none => panic!("logfile does not exist!"),
};
}
}
}
impl simplelogger {
pub fn init() -> result<(), setloggererror> {
let path = path::new("log/trace.log");
let display = path.display();
// open a file in write-only mode, returns `io::result<file>`
let mut file = match file::create(&path) {
err(why) => panic!("couldn't create {}: {}", display, error::description(&why)),
ok(file) => file,
};
log::set_logger(|max_log_level| {
max_log_level.set(loglevelfilter::info);
box::new(simplelogger { logfile: some(file) })
})
}
}