#[cfg(feature = "log")]
use tracing::level_filters::LevelFilter;
#[cfg(feature = "log")]
use tracing_appender::rolling::{RollingFileAppender, Rotation};
#[cfg(feature = "log")]
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer};
#[cfg(feature = "log")]
pub enum CLogLevel {
Trace,
Debug,
Info,
Warn,
Error,
}
#[cfg(feature = "log")]
pub use tracing::{debug, error, info, trace, warn};
#[cfg(feature = "log")]
fn from_cloglevel(level: &CLogLevel) -> LevelFilter {
match level {
CLogLevel::Trace => LevelFilter::TRACE,
CLogLevel::Debug => LevelFilter::DEBUG,
CLogLevel::Info => LevelFilter::INFO,
CLogLevel::Warn => LevelFilter::WARN,
CLogLevel::Error => LevelFilter::ERROR,
}
}
#[cfg(feature = "log")]
pub fn default_console_log(log_level: CLogLevel) {
let timer = tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d %H:%M:%S".to_owned());
let console_layer = tracing_subscriber::fmt::layer()
.with_timer(timer.clone())
.with_target(true)
.with_line_number(true)
.with_writer(std::io::stdout)
.with_ansi(true)
.with_filter(from_cloglevel(&log_level));
tracing_subscriber::registry().with(console_layer).init();
}
#[cfg(feature = "log")]
macro_rules! define_console_log_functions {
($($name:ident, $level:ident);* $(;)?) => {
$(
#[cfg(feature = "log")]
pub fn $name() {
default_console_log(CLogLevel::$level);
}
)*
};
}
#[cfg(feature = "log")]
define_console_log_functions! {
dcl_info, Info;
dcl_debug, Debug;
dcl_trace, Trace;
dcl_warn, Warn;
dcl_error, Error;
}
#[cfg(feature = "log")]
pub fn default_file_log(
log_level: CLogLevel,
log_path: &str,
log_file_name: &str,
max_log_files: Option<usize>,
) {
let timer = tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d %H:%M:%S".to_owned());
let mut file_appender = RollingFileAppender::builder()
.rotation(Rotation::DAILY)
.filename_prefix(log_file_name)
.filename_suffix("log");
if let Some(max_log_files) = max_log_files {
file_appender = file_appender.max_log_files(max_log_files);
};
let file_appender = file_appender.build(log_path).unwrap();
let file_layer = tracing_subscriber::fmt::layer()
.with_timer(timer)
.with_target(true)
.with_line_number(true)
.with_ansi(false)
.with_writer(file_appender)
.with_filter(from_cloglevel(&log_level));
tracing_subscriber::registry().with(file_layer).init();
}
#[cfg(feature = "log")]
pub fn default_log(
log_level: CLogLevel,
log_path: &str,
log_file_name: &str,
max_log_files: Option<usize>,
) {
let timer = tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d %H:%M:%S".to_owned());
let console_layer = tracing_subscriber::fmt::layer()
.with_timer(timer.clone())
.with_target(true)
.with_line_number(true)
.with_writer(std::io::stdout)
.with_ansi(true)
.with_filter(from_cloglevel(&log_level));
let mut file_appender = RollingFileAppender::builder()
.rotation(Rotation::DAILY)
.filename_prefix(log_file_name)
.filename_suffix("log");
if let Some(max_log_files) = max_log_files {
file_appender = file_appender.max_log_files(max_log_files);
};
let file_appender = file_appender.build(log_path).unwrap();
let file_layer = tracing_subscriber::fmt::layer()
.with_timer(timer)
.with_target(true)
.with_line_number(true)
.with_ansi(false)
.with_writer(file_appender)
.with_filter(from_cloglevel(&log_level));
tracing_subscriber::registry()
.with(file_layer)
.with(console_layer)
.init();
}
#[test]
#[cfg(feature = "log")]
fn test_console_log() {
default_console_log(CLogLevel::Trace);
tracing::trace!("trace");
tracing::debug!("debug");
tracing::info!("info");
tracing::warn!("warn");
tracing::error!("error");
}
#[test]
#[cfg(feature = "log")]
fn test_file_log() {
default_file_log(CLogLevel::Trace, "./", "test", None);
tracing::trace!("trace");
tracing::debug!("debug");
tracing::info!("info");
tracing::warn!("warn");
tracing::error!("error");
}
#[test]
#[cfg(feature = "log")]
fn test_log() {
default_log(CLogLevel::Trace, "./", "test", None);
tracing::trace!("trace");
tracing::debug!("debug");
tracing::info!("info");
tracing::warn!("warn");
tracing::error!("error");
}