bflog 0.1.0

Very tiny logging framework made for microservices.
Documentation
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 {
      // Load level from the BFLOG_LEVEL env var.
      level: env::var("BFLOG_LEVEL")
        .ok()
        .and_then(Severity::from_str)
        .unwrap_or_default(),

      // Load format from the BFLOG_FORMAT env var.
      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(),
  )
}