use crate::metrics::BRIGHTDATA_METRICS;
use serde_json::Value;
use std::collections::HashMap;
use std::time::Instant;
pub struct EnhancedLogger;
impl EnhancedLogger {
pub async fn log_brightdata_request_enhanced(
execution_id: &str,
zone: &str,
url: &str,
payload: Value,
status: u16,
response_headers: HashMap<String, String>,
data_format: &str,
raw_content: &str,
filtered_content: Option<&str>,
duration: std::time::Duration,
mcp_session_id: Option<&str>, ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
if let Err(e) = crate::extras::logger::JSON_LOGGER.log_brightdata_request(
execution_id,
zone,
url,
payload.clone(),
status,
response_headers.clone(),
data_format
).await {
log::warn!("Failed to log to existing logger: {}", e);
}
if let Err(e) = BRIGHTDATA_METRICS.log_call(
execution_id,
url,
zone,
"raw", Some(data_format),
payload,
status,
response_headers,
raw_content,
filtered_content,
duration.as_millis() as u64,
None, mcp_session_id, ).await {
log::warn!("Failed to log to metrics logger: {}", e);
} else {
if let Some(session_id) = mcp_session_id {
log::info!("📊 Logged to metrics with session context: {}", session_id);
} else {
log::info!("📊 Logged to metrics without session context");
}
}
Ok(())
}
pub async fn time_and_log_operation<F, R, E>(
execution_id: &str,
zone: &str,
url: &str,
payload: Value,
data_format: &str,
operation: F,
mcp_session_id: Option<&str>, ) -> Result<(R, String), E>
where
F: std::future::Future<Output = Result<(R, String, u16, HashMap<String, String>), E>>,
{
let start_time = Instant::now();
match operation.await {
Ok((result, content, status, headers)) => {
let duration = start_time.elapsed();
if let Err(e) = Self::log_brightdata_request_enhanced(
execution_id,
zone,
url,
payload,
status,
headers,
data_format,
&content,
None, duration,
mcp_session_id, ).await {
log::warn!("Failed to log operation: {}", e);
}
Ok((result, content))
}
Err(e) => {
let duration = start_time.elapsed();
let empty_headers = HashMap::new();
if let Err(log_err) = Self::log_brightdata_request_enhanced(
execution_id,
zone,
url,
payload,
500, empty_headers,
data_format,
"Operation failed",
None,
duration,
mcp_session_id, ).await {
log::warn!("Failed to log failed operation: {}", log_err);
}
Err(e)
}
}
}
pub async fn initialize_mcp_session(session_id: &str) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
log::info!("🎯 Initializing MCP session in enhanced logger: {}", session_id);
BRIGHTDATA_METRICS.mark_new_session(session_id).await?;
Ok(())
}
pub fn get_session_metrics(session_id: &str) -> serde_json::Value {
let session_calls = BRIGHTDATA_METRICS.get_calls_for_session(session_id);
let session_call_count = BRIGHTDATA_METRICS.get_session_call_count(session_id);
let mut service_breakdown = HashMap::new();
let mut total_duration = 0u64;
let mut successful_calls = 0u64;
let mut total_data_kb = 0.0f64;
for call in &session_calls {
let service_name = format!("{:?}", call.service);
*service_breakdown.entry(service_name).or_insert(0u64) += 1;
total_duration += call.duration_ms;
if call.success {
successful_calls += 1;
}
total_data_kb += call.filtered_data_size_kb;
}
serde_json::json!({
"session_id": session_id,
"total_calls": session_call_count,
"successful_calls": successful_calls,
"success_rate": if session_call_count > 0 {
successful_calls as f64 / session_call_count as f64 * 100.0
} else {
0.0
},
"total_duration_ms": total_duration,
"average_duration_ms": if session_call_count > 0 {
total_duration as f64 / session_call_count as f64
} else {
0.0
},
"total_data_kb": total_data_kb,
"average_data_kb": if session_call_count > 0 {
total_data_kb / session_call_count as f64
} else {
0.0
},
"service_breakdown": service_breakdown,
"timestamp": chrono::Utc::now().to_rfc3339()
})
}
pub fn get_all_sessions_summary() -> serde_json::Value {
let all_sessions = BRIGHTDATA_METRICS.get_all_sessions();
let total_calls = BRIGHTDATA_METRICS.get_total_call_count();
let sessions_data: Vec<serde_json::Value> = all_sessions.iter()
.map(|(session_id, call_count)| {
serde_json::json!({
"session_id": session_id,
"call_count": call_count,
"percentage_of_total": if total_calls > 0 {
*call_count as f64 / total_calls as f64 * 100.0
} else {
0.0
}
})
})
.collect();
serde_json::json!({
"total_sessions": all_sessions.len(),
"total_calls_across_all_sessions": total_calls,
"sessions": sessions_data,
"timestamp": chrono::Utc::now().to_rfc3339()
})
}
}