diff --git a/src/logging.rs b/src/logging.rs index 0cc6cec..4f66ffd 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -16,12 +16,20 @@ impl RequestLogger { } } - pub fn log_success(self, status_code: u8) { - println!("{} \"{}\" {}", self.client_ip, self.request_url, status_code); - } + pub fn log_error(self, status_code: u8, error_message: &str) { - eprintln!("{} \"{}\" {} \"{}\"", self.client_ip, self.request_url, status_code, error_message); + let level = match status_code { + 41 | 51 => tracing::Level::WARN, + 59 => tracing::Level::ERROR, + _ => tracing::Level::ERROR, + }; + + match level { + tracing::Level::WARN => tracing::warn!("{} \"{}\" {} \"{}\"", self.client_ip, self.request_url, status_code, error_message), + tracing::Level::ERROR => tracing::error!("{} \"{}\" {} \"{}\"", self.client_ip, self.request_url, status_code, error_message), + _ => {} + } } @@ -35,8 +43,28 @@ fn extract_client_ip(stream: &TlsStream) -> String { } } -pub fn init_logging(_level: &str) { - // Simple logging using stdout/stderr - systemd will capture this +pub fn init_logging(level: &str) { + use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; + + let level = match level.to_lowercase().as_str() { + "error" => tracing::Level::ERROR, + "warn" => tracing::Level::WARN, + "info" => tracing::Level::INFO, + "debug" => tracing::Level::DEBUG, + "trace" => tracing::Level::TRACE, + _ => { + eprintln!("Warning: Invalid log level '{}', defaulting to 'info'", level); + tracing::Level::INFO + } + }; + + tracing_subscriber::registry() + .with(tracing_subscriber::fmt::layer() + .compact() + .with_target(false) + .with_thread_ids(false)) + .with(tracing_subscriber::filter::LevelFilter::from_level(level)) + .init(); } #[cfg(test)] diff --git a/src/main.rs b/src/main.rs index 2adb9e6..7ac8c44 100644 --- a/src/main.rs +++ b/src/main.rs @@ -131,6 +131,7 @@ async fn main() { loop { let (stream, _) = listener.accept().await.unwrap(); + tracing::debug!("Accepted connection from {}", stream.peer_addr().unwrap_or_else(|_| "unknown".parse().unwrap())); let acceptor = acceptor.clone(); let dir = root.clone(); let expected_host = "localhost".to_string(); // Override for testing diff --git a/src/server.rs b/src/server.rs index 2b140e4..d1b744b 100644 --- a/src/server.rs +++ b/src/server.rs @@ -17,10 +17,17 @@ pub async fn serve_file( ) -> io::Result<()> { if file_path.exists() && file_path.is_file() { let mime_type = get_mime_type(file_path); + let header = format!("20 {}\r\n", mime_type); + stream.write_all(header.as_bytes()).await?; + // Log success after sending header + let client_ip = match stream.get_ref().0.peer_addr() { + Ok(addr) => addr.to_string(), + Err(_) => "unknown".to_string(), + }; + tracing::info!("{} \"file:{}\" 20 \"Success\"", client_ip, file_path.display()); + // Then send body let content = fs::read(file_path)?; - let mut response = format!("20 {}\r\n", mime_type).into_bytes(); - response.extend(content); - stream.write_all(&response).await?; + stream.write_all(&content).await?; stream.flush().await?; Ok(()) } else { @@ -118,10 +125,12 @@ pub async fn handle_connection( // Serve the file match serve_file(&mut stream, &file_path).await { - Ok(_) => logger.log_success(20), + Ok(_) => { + // Success already logged in serve_file + } Err(_) => { - // This shouldn't happen since we check existence, but handle gracefully - logger.log_error(51, "File not found"); + // File transmission failed + logger.log_error(51, "File transmission failed"); let _ = send_response(&mut stream, "51 Not found\r\n").await; } } @@ -155,7 +164,6 @@ pub async fn handle_connection( } ACTIVE_REQUESTS.fetch_sub(1, Ordering::Relaxed); - eprintln!("DEBUG: Request completed, count decremented"); Ok(()) }