use tracing::{Level, Subscriber};
use std::{io::{stdout, Write}};
use tracing_subscriber::{self, EnvFilter};
use crate::writers::{FileWriter, MakeCompositeWriter};
pub struct TraceListenerOptions {
level: Level,
is_stdout: bool,
cleanup_file: bool,
include_thread_ids: bool,
include_thread_names: bool,
file_path: String,
filter: EnvFilter,
}
impl Default for TraceListenerOptions {
fn default() -> Self {
return TraceListenerOptions {
level: Level::TRACE,
is_stdout: true,
cleanup_file: false,
include_thread_ids: false,
include_thread_names: false,
file_path: String::new(),
filter: EnvFilter::default(),
};
}
}
impl TraceListenerOptions {
pub fn new() -> Self {
return TraceListenerOptions::default();
}
pub fn with_stdout(self, is_stdout: bool) -> Self {
return TraceListenerOptions { is_stdout, ..self };
}
pub fn with_level(self, level: Level) -> Self {
return TraceListenerOptions { level, ..self };
}
pub fn with_file_path<S: AsRef<str> + ToString>(self, file_path: S, cleanup_file: bool) -> Self {
let file_path = file_path.to_string();
return TraceListenerOptions { file_path, cleanup_file: cleanup_file, ..self };
}
pub fn with_thread_names(self, include_thread_names: bool) -> Self {
return TraceListenerOptions { include_thread_names, ..self };
}
pub fn with_thread_ids(self, include_thread_ids: bool) -> Self {
return TraceListenerOptions { include_thread_ids, ..self };
}
pub fn with_env_filter(self, filter: impl Into<EnvFilter>) -> Self {
let filter = filter.into();
return TraceListenerOptions { filter, ..self };
}
}
pub fn create_trace_listener(
options: TraceListenerOptions,
) -> Box<dyn Subscriber + Send + Sync> {
let TraceListenerOptions {
file_path,
is_stdout,
cleanup_file,
include_thread_names,
include_thread_ids,
filter,
..
} = options;
let file_writer = FileWriter::new(&file_path, cleanup_file);
let stdout_writer: Box<dyn Write + Send + Sync> = Box::new(stdout());
let mut writers: Vec<Box<dyn Write + Send + Sync>> = vec![];
if file_path.len() > 0 {
writers.push(file_writer);
}
if is_stdout {
writers.push(stdout_writer);
}
let make_composite_writer = MakeCompositeWriter::new(writers);
let collector = tracing_subscriber::fmt()
.with_max_level(options.level)
.with_target(false)
.with_thread_ids(include_thread_ids)
.with_thread_names(include_thread_names)
.with_writer(make_composite_writer)
.with_env_filter(filter)
.finish();
return Box::new(collector);
}