use log::{self, LogRecord, LogLevelFilter, LogMetadata, SetLoggerError};
use mysql::conn::MyOpts;
use mysql::conn::pool::MyPool;
use std::sync::{Arc, Mutex};
pub type LogFn = fn(&LogRecord, &mut MyPool);
pub struct MysqlLogger {
pool: Arc<Mutex<MyPool>>,
outputfn: Arc<Mutex<LogFn>>,
}
impl MysqlLogger {
pub fn new(opts: MyOpts, create: bool, ofn: LogFn) -> MysqlLogger {
let pool = match MyPool::new(opts) {
Ok(pool) => pool,
Err(e) => panic!("Unable to initialize MysqlLogger! {}", e),
};
if create {
match pool.prep_exec("DROP TABLE log", ()) {
Ok(_) => {}
Err(e) => println!("{}", e),
}
match pool.prep_exec(r"CREATE TABLE log (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
created VARCHAR(255) NOT NULL,
level VARCHAR(255) NOT NULL,
line VARCHAR(255) NOT NULL,
module VARCHAR(255) NOT NULL,
message VARCHAR(255) NOT NULL
)",
()) {
Ok(_) => {}
Err(e) => panic!("Unable to create log table! {}", e),
}
}
MysqlLogger {
pool: Arc::new(Mutex::new(pool)),
outputfn: Arc::new(Mutex::new(ofn)),
}
}
}
impl log::Log for MysqlLogger {
fn enabled(&self, _: &LogMetadata) -> bool {
true
}
fn log(&self, record: &LogRecord) {
if self.enabled(record.metadata()) {
match self.pool.lock() {
Ok(ref mut pool) => {
match self.outputfn.lock() {
Ok(ref mut f) => {
f(record, pool);
}
Err(e) => {
println!("Unable to acquire lock! {}", e);
}
};
}
Err(e) => {
println!("Unable to acquire mutex lock! {:?}", e);
}
}
}
}
}
pub fn init_mysql_logger(level: LogLevelFilter, logger: MysqlLogger) -> Result<(), SetLoggerError> {
log::set_logger(|max_log_level| {
max_log_level.set(level);
Box::new(logger)
})
}