use pad::{PadStr, Alignment};
use log::{LogLevel, LogMetadata, LogRecord, Log};
use error::Result;
use handler::Handler;
use poll::*;
pub trait LoggingBackend
where Self: Handler<EpollEvent> + 'static
{
fn level(&self) -> LogLevel;
fn setup(&self, epfd: &EpollFd) -> Result<Box<Log>>;
}
pub struct SimpleLogging {
level: LogLevel,
}
impl SimpleLogging {
pub fn new(level: LogLevel) -> SimpleLogging {
SimpleLogging { level: level }
}
}
struct TracingLogger {
level: LogLevel,
}
impl Log for TracingLogger {
fn enabled(&self, metadata: &LogMetadata) -> bool {
metadata.level() <= self.level
}
fn log(&self, record: &LogRecord) {
if self.enabled(record.metadata()) {
let location = record.location();
let ms = format!("{:.*}",
3,
((::time::precise_time_ns() % 1_000_000_000) / 1_000_000));
println!("{}.{} {:<5} {:<20}:{} - {}",
::time::strftime("%Y-%m-%d %H:%M:%S", &::time::now()).unwrap(),
ms.pad(3, '0', Alignment::Right, true),
record.level().to_string(),
location.file(),
location.line(),
record.args());
}
}
}
impl LoggingBackend for SimpleLogging {
fn level(&self) -> LogLevel {
self.level
}
fn setup(&self, _: &EpollFd) -> Result<Box<Log>> {
Ok(Box::new(TracingLogger { level: self.level }))
}
}
impl Handler<EpollEvent> for SimpleLogging {
fn is_terminated(&self) -> bool {
false
}
fn ready(&mut self, _: &EpollEvent) {
}
}