use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tracing::Level;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum OutputFormat {
Text,
Json,
JsonCompact,
}
impl Default for OutputFormat {
fn default() -> Self {
Self::Text
}
}
#[derive(Debug, Clone)]
pub struct TracingConfig {
pub enable_http_tracing: bool,
pub enable_llm_tracing: bool,
pub enable_performance_monitoring: bool,
pub enable_error_tracking: bool,
pub enable_stream_tracing: bool,
pub enable_tool_tracing: bool,
pub log_level: Level,
pub output_format: OutputFormat,
pub log_file: Option<PathBuf>,
pub max_log_file_size: Option<u64>,
pub log_file_rotation_count: Option<usize>,
pub include_bodies: bool,
pub max_body_size: usize,
pub pretty_json: bool,
pub include_sensitive_headers: bool,
pub mask_sensitive_values: bool,
pub custom_fields: std::collections::HashMap<String, String>,
pub enable_console: bool,
pub enable_file: bool,
pub sampling_rate: f64,
}
impl Default for TracingConfig {
fn default() -> Self {
Self {
enable_http_tracing: true,
enable_llm_tracing: true,
enable_performance_monitoring: true,
enable_error_tracking: true,
enable_stream_tracing: false, enable_tool_tracing: true,
log_level: Level::INFO,
output_format: OutputFormat::Text,
log_file: None,
max_log_file_size: Some(100 * 1024 * 1024), log_file_rotation_count: Some(5),
include_bodies: false, max_body_size: 1024, pretty_json: false,
include_sensitive_headers: false,
mask_sensitive_values: true, custom_fields: std::collections::HashMap::new(),
enable_console: true,
enable_file: false,
sampling_rate: 1.0,
}
}
}
impl TracingConfig {
pub fn builder() -> TracingConfigBuilder {
TracingConfigBuilder::default()
}
pub fn debug() -> Self {
Self {
log_level: Level::DEBUG,
include_bodies: true,
max_body_size: 10 * 1024, enable_stream_tracing: true,
..Default::default()
}
}
pub fn production() -> Self {
Self {
log_level: Level::WARN,
output_format: OutputFormat::Json,
include_bodies: false,
include_sensitive_headers: false,
enable_stream_tracing: false,
enable_console: false,
enable_file: true,
sampling_rate: 0.1, ..Default::default()
}
}
pub fn performance() -> Self {
Self {
enable_http_tracing: false,
enable_llm_tracing: false,
enable_performance_monitoring: true,
enable_error_tracking: true,
enable_stream_tracing: false,
enable_tool_tracing: false,
log_level: Level::INFO,
output_format: OutputFormat::Json,
..Default::default()
}
}
pub fn development() -> Self {
Self {
log_level: Level::DEBUG,
output_format: OutputFormat::Text,
enable_console: true,
enable_file: false,
enable_http_tracing: true,
enable_llm_tracing: true,
enable_performance_monitoring: true,
enable_error_tracking: true,
enable_stream_tracing: false,
enable_tool_tracing: true,
include_bodies: true,
max_body_size: 4096,
pretty_json: true, include_sensitive_headers: false,
sampling_rate: 1.0,
..Default::default()
}
}
pub fn minimal() -> Self {
Self {
log_level: Level::INFO,
output_format: OutputFormat::Text,
enable_console: true,
enable_file: false,
enable_http_tracing: false,
enable_llm_tracing: true,
enable_performance_monitoring: false,
enable_error_tracking: true,
enable_stream_tracing: false,
enable_tool_tracing: false,
include_bodies: false,
max_body_size: 1024,
include_sensitive_headers: false,
sampling_rate: 1.0,
..Default::default()
}
}
pub fn json_production() -> Self {
Self {
log_level: Level::WARN,
output_format: OutputFormat::Json,
enable_console: false,
enable_file: true,
enable_http_tracing: false,
enable_llm_tracing: true,
enable_performance_monitoring: true,
enable_error_tracking: true,
enable_stream_tracing: false,
enable_tool_tracing: false,
include_bodies: false,
max_body_size: 1024,
include_sensitive_headers: false,
sampling_rate: 0.1, ..Default::default()
}
}
pub fn disabled() -> Self {
Self {
log_level: Level::ERROR,
output_format: OutputFormat::Text,
enable_console: false,
enable_file: false,
enable_http_tracing: false,
enable_llm_tracing: false,
enable_performance_monitoring: false,
enable_error_tracking: false,
enable_stream_tracing: false,
enable_tool_tracing: false,
include_bodies: false,
max_body_size: 0,
include_sensitive_headers: false,
sampling_rate: 0.0,
..Default::default()
}
}
pub fn with_pretty_json(mut self, pretty: bool) -> Self {
self.pretty_json = pretty;
self
}
pub fn with_mask_sensitive_values(mut self, mask: bool) -> Self {
self.mask_sensitive_values = mask;
self
}
}
#[derive(Debug, Default, Clone)]
pub struct TracingConfigBuilder {
config: TracingConfig,
}
impl TracingConfigBuilder {
pub fn from_config(config: TracingConfig) -> Self {
Self { config }
}
pub fn enable_http_tracing(mut self, enable: bool) -> Self {
self.config.enable_http_tracing = enable;
self
}
pub fn enable_llm_tracing(mut self, enable: bool) -> Self {
self.config.enable_llm_tracing = enable;
self
}
pub fn enable_performance_monitoring(mut self, enable: bool) -> Self {
self.config.enable_performance_monitoring = enable;
self
}
pub fn enable_error_tracking(mut self, enable: bool) -> Self {
self.config.enable_error_tracking = enable;
self
}
pub fn enable_stream_tracing(mut self, enable: bool) -> Self {
self.config.enable_stream_tracing = enable;
self
}
pub fn enable_tool_tracing(mut self, enable: bool) -> Self {
self.config.enable_tool_tracing = enable;
self
}
pub fn log_level<L: Into<Level>>(mut self, level: L) -> Self {
self.config.log_level = level.into();
self
}
pub fn log_level_str(mut self, level: &str) -> Result<Self, String> {
let level = match level.to_lowercase().as_str() {
"trace" => Level::TRACE,
"debug" => Level::DEBUG,
"info" => Level::INFO,
"warn" => Level::WARN,
"error" => Level::ERROR,
_ => return Err(format!("Invalid log level: {level}")),
};
self.config.log_level = level;
Ok(self)
}
pub fn output_format(mut self, format: OutputFormat) -> Self {
self.config.output_format = format;
self
}
pub fn log_file<P: Into<PathBuf>>(mut self, path: P) -> Self {
self.config.log_file = Some(path.into());
self.config.enable_file = true;
self
}
pub fn max_log_file_size(mut self, size: u64) -> Self {
self.config.max_log_file_size = Some(size);
self
}
pub fn log_file_rotation_count(mut self, count: usize) -> Self {
self.config.log_file_rotation_count = Some(count);
self
}
pub fn include_bodies(mut self, include: bool) -> Self {
self.config.include_bodies = include;
self
}
pub fn max_body_size(mut self, size: usize) -> Self {
self.config.max_body_size = size;
self
}
pub fn pretty_json(mut self, pretty: bool) -> Self {
self.config.pretty_json = pretty;
self
}
pub fn include_sensitive_headers(mut self, include: bool) -> Self {
self.config.include_sensitive_headers = include;
self
}
pub fn mask_sensitive_values(mut self, mask: bool) -> Self {
self.config.mask_sensitive_values = mask;
self
}
pub fn custom_field<K: Into<String>, V: Into<String>>(mut self, key: K, value: V) -> Self {
self.config.custom_fields.insert(key.into(), value.into());
self
}
pub fn enable_console(mut self, enable: bool) -> Self {
self.config.enable_console = enable;
self
}
pub fn enable_file(mut self, enable: bool) -> Self {
self.config.enable_file = enable;
self
}
pub fn sampling_rate(mut self, rate: f64) -> Self {
self.config.sampling_rate = rate.clamp(0.0, 1.0);
self
}
pub fn build(self) -> TracingConfig {
self.config
}
}