diff --git a/Cargo.lock b/Cargo.lock index 3676194a..28afe11f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2145,6 +2145,7 @@ dependencies = [ "derivative", "derive_more", "directories", + "etcetera", "float-pretty-print", "futures", "hashbrown 0.15.2", @@ -2172,6 +2173,7 @@ dependencies = [ "thiserror 2.0.11", "tokio", "tracing", + "tracing-appender", "tracing-indicatif", "tracing-subscriber", "typed-builder", @@ -4160,6 +4162,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-appender" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +dependencies = [ + "crossbeam-channel", + "thiserror 1.0.69", + "time", + "tracing-subscriber", +] + [[package]] name = "tracing-attributes" version = "0.1.28" diff --git a/Cargo.toml b/Cargo.toml index 3f73301f..ae763751 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,8 @@ strum = "0.26.3" human-panic = "2.0.2" crossbeam = { version = "0.8.4", features = ["crossbeam-channel"] } uuid = { version = "1.12.1", features = ["v4"] } +etcetera = "0.8.0" +tracing-appender = "0.2.3" [features] default = ["tui"] diff --git a/docs/logging.md b/docs/logging.md new file mode 100644 index 00000000..3f91be5a --- /dev/null +++ b/docs/logging.md @@ -0,0 +1,74 @@ +# Logging Configuration + +Neuronek implements a comprehensive logging system that provides both file-based and console-based logging capabilities. The logging system is designed to be XDG-compliant and supports multiple output layers with different configurations. + +## Log File Location + +Log files are stored following the XDG Base Directory Specification: + +- **Development/Debug Mode**: Logs are stored in the system's temporary directory as `neuronek.sqlite` +- **Production Mode**: Logs are stored in the XDG cache directory: `~/.cache/neuronek/logs/debug.log` (Linux) or equivalent on other platforms + +## Logging Layers + +The logging system implements two main layers: + +### 1. File Appender + +The file appender writes detailed logs to a file with the following characteristics: + +- Includes file names and line numbers for precise error tracking +- Records thread IDs for concurrent operation debugging +- Maintains detailed context for debugging purposes +- Stores logs in the XDG-compliant directory structure + +### 2. Console Appender + +The console appender provides a streamlined output to stderr: + +- Simplified output without file names or line numbers +- No thread IDs to keep the output clean +- ANSI color support for better readability +- Focused on user-relevant information +- Writes to stderr for clean JSON output compatibility + +## Log Levels + +The logging system supports multiple log levels through the `tracing` crate: + +- ERROR: For critical issues that prevent normal operation +- WARN: For important issues that don't stop execution +- INFO: For general information about program operation +- DEBUG: For detailed information useful during development +- TRACE: For very detailed debugging information + +By default, the logging level is set to INFO, but this can be adjusted through environment variables. + +## Configuration + +The logging system integrates with Neuronek's configuration system and respects the following settings: + +- Log file location is determined by the application mode (debug/release) +- Environment variables can control the logging level +- XDG base directories are used for log file storage + +## Usage Example + +```rust +// Log messages at different levels +error!("Critical error occurred"); +warn!("Warning: operation may be slow"); +info!("Operation completed successfully"); +debug!("Detailed debug information"); +trace!("Very detailed trace information"); +``` + +## Implementation Details + +The logging system is implemented using the following crates: + +- `tracing`: Core logging functionality +- `tracing-subscriber`: Logging subscriber implementation +- `etcetera`: XDG base directory handling + +The setup is handled in `src/core/logging.rs` and integrates with the application's configuration system in `src/core/config.rs`. \ No newline at end of file diff --git a/src/core/logging.rs b/src/core/logging.rs index ea62d8b2..a728726e 100644 --- a/src/core/logging.rs +++ b/src/core/logging.rs @@ -1,13 +1,43 @@ -// TODO: Implement logging -pub fn setup_logger() -{ - // let log_file_path = std::env::current_dir().unwrap().join("debug.log"); - // let _ = std::fs::remove_file(&log_file_path); - // - // use tracing_subscriber::fmt; - // use tracing_subscriber::prelude::*; - // - // let file_layer = fmt::layer().with_writer(std::fs::File::create(log_file_path).unwrap()); - // - // tracing_subscriber::registry().with(file_layer).init(); +use etcetera::base_strategy::{BaseStrategy, Xdg}; +use std::fs::create_dir_all; +use tracing_subscriber::{fmt, prelude::*, EnvFilter}; +use tracing_appender::rolling::{RollingFileAppender, Rotation}; +use tracing_appender::non_blocking::WorkerGuard; + +pub fn setup_logger() -> Result> { + // Get XDG data directory + let xdg = Xdg::new()?.cache_dir().join("neuronek").join("logs"); + create_dir_all(&xdg)?; + + let file_appender = RollingFileAppender::new( + Rotation::DAILY, + &xdg, + "neuronek" + ); + + let (non_blocking_appender, guard) = tracing_appender::non_blocking(file_appender); + + let file_layer = fmt::layer() + .with_file(true) + .with_line_number(true) + .with_thread_ids(true) + .with_target(false) + .with_writer(non_blocking_appender); + + let console_layer = fmt::layer() + .with_target(false) + .with_thread_ids(false) + .with_file(false) + .with_line_number(false) + .with_ansi(true) + .with_writer(std::io::stderr); + + tracing_subscriber::registry() + .with(EnvFilter::from_default_env() + .add_directive(tracing::Level::INFO.into())) + .with(file_layer) + .with(console_layer) + .init(); + + Ok(guard) }