#![warn(missing_docs)]
#[macro_use]
extern crate slog;
extern crate slog_serde;
extern crate serde_json;
extern crate chrono;
use std::io;
use slog_serde::SerdeSerializer;
use slog::Record;
use slog::{Level, OwnedKeyValue, OwnedKeyValueList};
use slog::Level::*;
use slog::format;
use slog::ser::{PushLazy, ValueSerializer};
use std::borrow::Borrow;
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: Vec<OwnedKeyValue>,
}
impl Format {
pub fn new() -> Self {
Format {
newlines: true,
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::<&str>(record.msg().borrow())
})
),
}
}
pub fn build() -> FormatBuilder {
FormatBuilder::new()
}
pub fn new_nonewline() -> Self {
let mut json = Format::new();
json.newlines = false;
json
}
}
pub struct FormatBuilder {
newlines: bool,
values: Vec<OwnedKeyValue>,
}
impl FormatBuilder {
fn new() -> Self {
FormatBuilder {
newlines: true,
values: vec![],
}
}
pub fn build(self) -> Format {
Format {
values: self.values,
newlines: self.newlines,
}
}
pub fn set_newlines(&mut self, enabled: bool) -> &mut Self {
self.newlines = enabled;
self
}
pub fn add_key_values(&mut self, mut values: Vec<OwnedKeyValue>) -> &mut Self {
self.values.extend(values.drain(..));
self
}
pub fn add_key_value(&mut self, value: OwnedKeyValue) -> &mut Self {
self.values.push(value);
self
}
}
struct SkipFirstByte<W> {
first: bool,
io: W,
}
impl<W: io::Write> SkipFirstByte<W> {
fn new(io: W) -> Self {
SkipFirstByte {
first: true,
io: io,
}
}
fn into_inner(self) -> W {
self.io
}
}
impl<W: io::Write> io::Write for SkipFirstByte<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
if self.first && !buf.is_empty() {
self.first = false;
try!(self.io.write_all(&buf[1..]));
} else {
try!(self.io.write_all(buf))
}
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
self.io.flush()
}
}
impl format::Format for Format {
fn format(&self,
io: &mut io::Write,
rinfo: &Record,
logger_values: &OwnedKeyValueList)
-> io::Result<()> {
let _ = try!(write!(io, "{{"));
let mut serializer = serde_json::Serializer::new(SkipFirstByte::new(io));
{
let mut serializer = &mut SerdeSerializer(&mut serializer);
for &(ref k, ref v) in self.values.iter() {
try!(v.serialize(rinfo, k, serializer));
}
for &(ref k, ref v) in logger_values.iter() {
try!(v.serialize(rinfo, k, serializer));
}
for &(ref k, ref v) in rinfo.values().iter() {
try!(v.serialize(rinfo, k, serializer));
}
}
let mut io = serializer.into_inner().into_inner();
let _ = try!(io.write_all("}".as_bytes()));
if self.newlines {
let _ = try!(io.write_all("\n".as_bytes()));
}
Ok(())
}
}
pub fn new() -> Format {
Format::new()
}
pub fn build() -> FormatBuilder {
Format::build()
}