#[allow(unused_imports)]
#[macro_use]
extern crate slog;
mod collector_serializer;
mod glog_format;
mod http_local_slog_drain;
mod http_log_client;
mod kv_categorizer;
mod security;
mod simple_logger;
use crate::{
http_local_slog_drain::HttpLocalSlogDrain, http_log_client::HttpLogClient,
kv_categorizer::ErrorCategorizer,
};
use crossbeam::atomic::ArcCell;
use failure::prelude::*;
use glog_format::GlogFormat;
use lazy_static::lazy_static;
use slog::{o, Discard, Drain, FilterLevel, Logger, Never};
pub use slog::{slog_crit, slog_debug, slog_error, slog_info, slog_trace, slog_warn};
use slog_async::Async;
use slog_envlogger::{EnvLogger, LogBuilder};
pub use slog_scope::{crit, debug, error, info, trace, warn};
use slog_scope::{set_global_logger, GlobalLoggerGuard};
use slog_term::{PlainDecorator, TermDecorator};
use std::sync::{Arc, Mutex};
pub mod prelude {
pub use crate::{
log_collector_crit, log_collector_debug, log_collector_error, log_collector_info,
log_collector_trace, log_collector_warn,
security::{security_log, SecurityEvent},
};
pub use slog::{slog_crit, slog_debug, slog_error, slog_info, slog_trace, slog_warn};
pub use slog_scope::{crit, debug, error, info, trace, warn};
}
pub use simple_logger::{set_simple_logger, set_simple_logger_prefix};
pub fn set_default_global_logger(async_drain: bool, chan_size: Option<usize>) -> GlobalLoggerGuard {
let logger = create_default_root_logger(async_drain, chan_size);
set_global_logger(logger)
}
fn create_default_root_logger(async_drain: bool, chan_size: Option<usize>) -> Logger {
let drain = GlogFormat::new(PlainDecorator::new(::std::io::stderr()), ErrorCategorizer).fuse();
let logger = create_env_logger(drain);
get_logger(async_drain, chan_size, logger)
}
fn create_env_logger_with_level<D>(drain: D, level: FilterLevel) -> EnvLogger<D>
where
D: Drain<Err = Never, Ok = ()> + Send + 'static,
{
let mut builder = LogBuilder::new(drain);
builder = builder.filter(None, level);
if let Ok(s) = ::std::env::var("RUST_LOG") {
builder = builder.parse(&s);
}
builder.build()
}
fn create_env_logger<D>(drain: D) -> EnvLogger<D>
where
D: Drain<Err = Never, Ok = ()> + Send + 'static,
{
create_env_logger_with_level(drain, FilterLevel::Info)
}
fn create_test_root_logger() -> Logger {
let drain = GlogFormat::new(TermDecorator::new().build(), ErrorCategorizer).fuse();
let envlogger = create_env_logger_with_level(drain, FilterLevel::Debug);
Logger::root(Mutex::new(envlogger).fuse(), o!())
}
lazy_static! {
static ref TESTING_ENVLOGGER_GUARD: GlobalLoggerGuard = {
let logger = {
if ::std::env::var("RUST_LOG").is_ok() {
create_default_root_logger(false , None )
} else {
Logger::root(Discard, o!())
}
};
set_global_logger(logger)
};
static ref END_TO_END_TESTING_ENVLOGGER_GUARD: GlobalLoggerGuard = {
let logger = create_test_root_logger();
set_global_logger(logger)
};
}
lazy_static! {
static ref GLOBAL_LOG_COLLECTOR: ArcCell<Logger> =
ArcCell::new(Arc::new(Logger::root(Discard, o!())));
}
#[derive(Clone, Debug)]
pub enum LoggerType {
Http(String),
StdOutput,
}
pub fn set_global_log_collector(collector: LoggerType, is_async: bool, chan_size: Option<usize>) {
let log_collector = get_log_collector(collector, is_async, chan_size).unwrap();
GLOBAL_LOG_COLLECTOR.set(Arc::new(log_collector));
}
pub fn try_init_for_testing() {
::lazy_static::initialize(&TESTING_ENVLOGGER_GUARD);
}
pub fn init_for_e2e_testing() {
::lazy_static::initialize(&END_TO_END_TESTING_ENVLOGGER_GUARD);
}
fn get_log_collector(
collector: LoggerType,
is_async: bool,
chan_size: Option<usize>,
) -> Result<Logger> {
match collector {
LoggerType::Http(http_endpoint) => {
let client = HttpLogClient::new(http_endpoint);
let drain = HttpLocalSlogDrain::new(client?);
Ok(get_logger(is_async, chan_size, drain))
}
LoggerType::StdOutput => Ok(create_default_root_logger(is_async, chan_size)),
}
}
fn get_logger<D>(is_async: bool, chan_size: Option<usize>, drain: D) -> Logger
where
D: Drain<Err = Never, Ok = ()> + Send + 'static,
{
if is_async {
let async_builder = match chan_size {
Some(chan_size_inner) => Async::new(drain).chan_size(chan_size_inner),
None => Async::new(drain),
};
Logger::root(async_builder.build().fuse(), o!())
} else {
Logger::root(Mutex::new(drain).fuse(), o!())
}
}
pub fn with_logger<F, R>(f: F) -> R
where
F: FnOnce(&Logger) -> R,
{
f(&(*GLOBAL_LOG_COLLECTOR.get()))
}
#[macro_export]
macro_rules! log_collector_crit( ($($args:tt)+) => {
$crate::with_logger(|logger| slog_crit![logger, $($args)+])
};);
#[macro_export]
macro_rules! log_collector_error( ($($args:tt)+) => {
$crate::with_logger(|logger| slog_error![logger, $($args)+])
};);
#[macro_export]
macro_rules! log_collector_warn( ($($args:tt)+) => {
$crate::with_logger(|logger| slog_warn![logger, $($args)+])
};);
#[macro_export]
macro_rules! log_collector_info( ($($args:tt)+) => {
$crate::with_logger(|logger| slog_info![logger, $($args)+])
};);
#[macro_export]
macro_rules! log_collector_debug( ($($args:tt)+) => {
$crate::with_logger(|logger| slog_debug![logger, $($args)+])
};);
#[macro_export]
macro_rules! log_collector_trace( ($($args:tt)+) => {
$crate::with_logger(|logger| slog_trace![logger, $($args)+])
};);