use chrono::prelude::*;
use serde_json;
use std::env;
use std::io::{self, Write};
use super::prelude::*;
pub struct Log {
pub format: Format,
pub level: Severity,
}
impl Logging for Log {
fn raw_msg(&self, severity: Severity, msg: &str) -> io::Result<Option<ContextWriter>> {
if severity.to_level() < self.level.to_level() {
return Ok(None);
}
let mut output = Output::new(&severity);
match self.format {
Format::Json => {
output.write(b"{\"time\":\"")?;
write_time(&mut output)?;
write!(
&mut output,
"\",\"severity\":\"{}\",\"message\":",
severity.to_str()
)?;
serde_json::to_writer(&mut output, msg)?;
}
ref format => {
if format.is_colored() {
output.set_color(Color::BrightBlack)?;
}
write_time(&mut output)?;
if format.is_colored() {
output.set_color(match severity {
Severity::Debug => Color::Magenta,
Severity::Info => Color::BrightBlue,
Severity::Warn => Color::BrightYellow,
Severity::Error => Color::BrightRed,
})?;
}
if format.has_icons() {
write!(&mut output, " {}", severity.to_icon())?;
}
write!(&mut output, " {} ", severity.to_aligned_str())?;
if format.is_colored() {
output.reset_colors()?;
}
output.write(msg.as_bytes())?;
}
}
Ok(Some(ContextWriter::new(self.format.clone(), output)))
}
}
impl Default for Log {
fn default() -> Log {
Log {
level: env::var("BFLOG_LEVEL")
.ok()
.and_then(Severity::from_str)
.unwrap_or_default(),
format: env::var("BFLOG_FORMAT")
.ok()
.and_then(Format::from_str)
.unwrap_or_default(),
}
}
}
fn write_time(output: &mut impl io::Write) -> io::Result<()> {
let time = Local::now();
write!(
output,
"{:04}-{:02}-{:02}T{:02}:{:02}:{:02}{}",
time.year(),
time.month(),
time.day(),
time.hour(),
time.minute(),
time.second(),
time.offset(),
)
}