Menu
Public repository / master
AkurAI-Drive / desktop/src-tauri/src/logging.rs
Latest change 2d36cd6c72fc6a63a7edb87bb54a4020e50f2f8a - desktop: Tauri v2 tray + Google-Drive-style file browser app by olibuijr
//! Structured logging for screenshot-free diagnosis.
//!
//! Everything is logged to BOTH stdout and a file at
//! `$XDG_STATE_HOME/akurai-drive/desktop.log` (fallback
//! `~/.local/state/akurai-drive/desktop.log`). The verbosity comes from
//! `RUST_LOG`; when it is unset we default to `info,akurai_drive=debug` so the
//! app's own crates (`akurai_drive_desktop`, `akurai_drive_sync`) log at debug
//! while the noisy dependency tree stays at info.
use std::path::PathBuf;
use std::sync::OnceLock;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{fmt, EnvFilter};
// The non-blocking writer's worker guard must live for the whole process or logs
// are dropped on exit — park it in a process-lifetime cell.
static GUARD: OnceLock<WorkerGuard> = OnceLock::new();
/// `$XDG_STATE_HOME/akurai-drive` (or `~/.local/state/akurai-drive`).
pub fn log_dir() -> PathBuf {
let base = std::env::var_os("XDG_STATE_HOME")
.map(PathBuf::from)
.filter(|p| !p.as_os_str().is_empty())
.or_else(|| dirs::home_dir().map(|h| h.join(".local").join("state")))
.unwrap_or_else(|| PathBuf::from("."));
base.join("akurai-drive")
}
/// The full path of the desktop log file.
pub fn log_path() -> PathBuf {
log_dir().join("desktop.log")
}
/// Install the global subscriber. Safe to call once at startup.
pub fn init() {
let dir = log_dir();
if let Err(e) = std::fs::create_dir_all(&dir) {
eprintln!("akurai-drive: cannot create log dir {}: {e}", dir.display());
}
let file_appender = tracing_appender::rolling::never(&dir, "desktop.log");
let (file_writer, guard) = tracing_appender::non_blocking(file_appender);
let _ = GUARD.set(guard);
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("info,akurai_drive=debug"));
let stdout_layer = fmt::layer().with_target(true).with_writer(std::io::stdout);
let file_layer = fmt::layer()
.with_ansi(false)
.with_target(true)
.with_writer(file_writer);
if tracing_subscriber::registry()
.with(filter)
.with(stdout_layer)
.with(file_layer)
.try_init()
.is_err()
{
eprintln!("akurai-drive: tracing subscriber already initialized");
}
}