use std::collections::HashMap;
use hostname;
use log;
use log::set_boxed_logger;
use crate::{Backend, Error, Message, WireMessage};
use crate::errors::Result;
pub struct Logger {
hostname: String,
backend: Box<dyn Backend>,
default_metadata: HashMap<String, String>,
panic_on_error: bool,
}
impl Logger {
pub fn new(backend: Box<dyn Backend>) -> Result<Self> {
hostname::get_hostname()
.map(|hostname| Logger::new_with_hostname(backend, &hostname))
.ok_or_else(|| format_err!("Failed to determine local hostname")
.context(Error::LoggerCreateFailed)
.into())
}
pub fn new_with_hostname(backend: Box<dyn Backend>, hostname: &str) -> Logger {
Logger {
hostname: String::from(hostname),
backend: backend,
default_metadata: HashMap::new(),
panic_on_error: false,
}
}
pub fn install<T: Into<log::LevelFilter>>(self, log_level: T) -> Result<()> {
set_boxed_logger(Box::new(self))?;
log::set_max_level(log_level.into());
Ok(())
}
pub fn log_message(&self, msg: Message) {
let result = self.backend.log_message(WireMessage::new(msg, &self));
if result.is_err() && self.panic_on_error {
panic!(result.unwrap_err());
}
}
pub fn hostname(&self) -> &String {
&self.hostname
}
pub fn set_hostname<S: Into<String>>(&mut self, hostname: S) -> &mut Self {
self.hostname = hostname.into();
self
}
pub fn default_metadata(&self) -> &HashMap<String, String> {
&self.default_metadata
}
pub fn set_default_metadata<S, T>(
&mut self,
key: S,
value: T
) -> &mut Self
where
S: Into<String>,
T: Into<String>
{
self.default_metadata.insert(key.into(), value.into());
self
}
pub fn panic_on_error(&self) -> bool {
self.panic_on_error
}
pub fn enable_panic_on_error(&mut self) -> &mut Self {
self.panic_on_error = true;
self
}
pub fn disable_panic_on_error(&mut self) -> &mut Self {
self.panic_on_error = false;
self
}
}
impl log::Log for Logger {
fn enabled(&self, _: &log::Metadata) -> bool {
true
}
fn log(&self, record: &log::Record) {
if !self.enabled(record.metadata()) {
()
}
self.log_message(From::from(record))
}
fn flush(&self) {}
}