#![warn(missing_docs)]
#[macro_use]
extern crate slog;
extern crate slog_serde;
extern crate serde_json;
use std::io;
use slog_serde::SerdeSerializer;
use slog::Record;
use slog::{Level, OwnedKeyValue, OwnedKeyValueList};
use slog::Level::*;
use slog::format;
fn level_to_string(level: Level) -> &'static str {
match level {
Critical => "CRIT",
Error => "ERRO",
Warning => "WARN",
Info => "INFO",
Debug => "DEBG",
Trace => "TRCE",
}
}
pub struct Json {
newlines: bool,
values: Vec<OwnedKeyValue>,
}
impl Json {
pub fn new() -> Self {
Json {
newlines: true,
values: o!(
"ts" => move |rinfo : &Record| {
rinfo.ts().to_rfc3339()
},
"level" => move |rinfo : &Record| {
level_to_string(rinfo.level())
},
"msg" => move |rinfo : &Record| {
rinfo.msg().to_string()
}
),
}
}
pub fn build() -> JsonBuilder {
JsonBuilder::new()
}
pub fn new_nonewline() -> Self {
let mut json = Json::new();
json.newlines = false;
json
}
}
pub struct JsonBuilder {
newlines: bool,
values: Vec<OwnedKeyValue>,
}
impl JsonBuilder {
fn new() -> Self {
JsonBuilder {
newlines: true,
values: vec![],
}
}
pub fn build(self) -> Json {
Json {
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 Json {
fn format(&self,
io: &mut io::Write,
rinfo: &Record,
logger_values: &OwnedKeyValueList)
-> format::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() -> Json {
Json::new()
}
pub fn build() -> JsonBuilder {
Json::build()
}