#![warn(missing_docs)]
#[macro_use]
extern crate slog;
extern crate slog_serde;
extern crate slog_stream;
extern crate serde_json;
extern crate chrono;
use std::io;
use slog_serde::SerdeSerializer;
use slog::Record;
use slog::{Level, OwnedKeyValueList};
use slog::Level::*;
use slog::ser::{PushLazy, ValueSerializer, SyncMultiSerialize};
fn level_to_string(level: Level) -> &'static str {
match level {
Critical => "CRIT",
Error => "ERRO",
Warning => "WARN",
Info => "INFO",
Debug => "DEBG",
Trace => "TRCE",
}
}
pub struct Format {
newlines: bool,
values: OwnedKeyValueList,
}
impl Format {
pub fn new() -> FormatBuilder {
FormatBuilder::new()
}
}
pub struct FormatBuilder {
newlines: bool,
values: OwnedKeyValueList,
}
impl FormatBuilder {
fn new() -> Self {
FormatBuilder {
newlines: true,
values: OwnedKeyValueList::root(None),
}
}
pub fn build(self) -> Format {
Format {
values: self.values,
newlines: self.newlines,
}
}
pub fn set_newlines(mut self, enabled: bool) -> Self {
self.newlines = enabled;
self
}
pub fn add_key_values(mut self, values: Option<Box<SyncMultiSerialize>>) -> Self {
if let Some(v) = values {
self.values = OwnedKeyValueList::new(v, self.values);
}
self
}
pub fn add_key_value(mut self, value: Option<Box<SyncMultiSerialize>>) -> Self {
if let Some(v) = value {
self.values = OwnedKeyValueList::new(v, self.values);
}
self
}
pub fn add_default_keys(self) -> Self {
self.add_key_values(
o!(
"ts" => PushLazy(move |_ : &Record, ser : ValueSerializer| {
ser.serialize(chrono::Local::now().to_rfc3339())
}),
"level" => move |rinfo : &Record| {
level_to_string(rinfo.level())
},
"msg" => PushLazy(move |record : &Record, ser : ValueSerializer| {
ser.serialize(record.msg())
})
)
)
}
}
impl slog_stream::Format for Format {
fn format(&self,
io: &mut io::Write,
rinfo: &Record,
logger_values: &OwnedKeyValueList)
-> io::Result<()> {
let io = {
let serializer = serde_json::Serializer::new(io);
let mut serializer = try!(SerdeSerializer::start(serializer, None));
for (ref k, ref v) in self.values.iter() {
try!(v.serialize(rinfo, k, &mut serializer));
}
for (ref k, ref v) in logger_values.iter() {
try!(v.serialize(rinfo, k, &mut serializer));
}
for &(ref k, ref v) in rinfo.values().iter() {
try!(v.serialize(rinfo, k, &mut serializer));
}
let (serializer, res) = serializer.end();
let _ = try!(res);
serializer.into_inner()
};
if self.newlines {
let _ = try!(io.write_all("\n".as_bytes()));
}
Ok(())
}
}
pub fn new() -> FormatBuilder {
Format::new()
}
pub fn default() -> Format {
Format::new().add_default_keys().build()
}