use super::{DrainRef, OwnedKeyValue, Level, BorrowedKeyValue};
use std::sync::Arc;
use crossbeam::sync::ArcCell;
use std::{io};
use super::format;
use isatty::stderr_isatty;
use drain;
use chrono;
struct LoggerInner {
drain: DrainRef,
values: Vec<OwnedKeyValue>,
}
#[derive(Clone)]
pub struct Logger {
inner: Arc<LoggerInner>,
}
impl Logger {
#[doc(hidden)]
pub fn new_root(values : Vec<OwnedKeyValue>) -> Logger {
let drain = Arc::new(
ArcCell::new(
Arc::new(
Box::new(
drain::Streamer::new(
io::stderr(),
if stderr_isatty() {
format::Terminal::colored()
} else {
format::Terminal::plain()
}
)
) as Box<drain::Drain>
)
)
);
Logger{
inner: Arc::new(LoggerInner {
drain: drain,
values: values,
}),
}
}
#[doc(hidden)]
pub fn new(&self, values : Vec<OwnedKeyValue>) -> Logger {
let mut new_values = self.inner.values.clone();
new_values.extend_from_slice(&values);
Logger{
inner: Arc::new(LoggerInner {
drain: self.inner.drain.clone(),
values: new_values,
}),
}
}
pub fn set_drain<D : drain::Drain>(&self, drain : D) {
let _ = self.inner.drain.set(Arc::new(Box::new(drain)));
}
pub fn swap_drain(&self, drain : Arc<Box<drain::Drain>>) -> Arc<Box<drain::Drain>> {
self.inner.drain.set(drain)
}
#[doc(hidden)]
pub fn log<'a, 'b>(&'a self, lvl : Level, msg : &'a str, values : &'a[BorrowedKeyValue<'a>]) {
let info = RecordInfo {
ts: chrono::UTC::now(),
msg: msg.to_string(),
level: lvl,
};
self.inner.drain.get().log(&info, self.inner.values.as_slice(), values);
}
}
pub struct RecordInfo {
pub ts : chrono::DateTime<chrono::UTC>,
pub level : Level,
pub msg : String,
}