From 9bea038cb607c044b185979ddb9260d3a72bd9f0 Mon Sep 17 00:00:00 2001 From: Razvan Dimescu Date: Thu, 16 Apr 2026 19:12:42 +0300 Subject: [PATCH] fix(windows): unify config/data dir and add service log file config_dir() on Windows now returns data_dir() (ProgramData) so config, services.json, and log file are in the same place for both interactive and service contexts. Service mode writes logs to numa.log via env_logger pipe. Dashboard shows correct log path per OS. --- site/dashboard.html | 13 +++++-------- src/lib.rs | 7 ++----- src/main.rs | 31 +++++++++++++++++++++---------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/site/dashboard.html b/site/dashboard.html index 0e26752..fa2d965 100644 --- a/site/dashboard.html +++ b/site/dashboard.html @@ -1153,13 +1153,10 @@ async function refresh() { const isWin = stats.data_dir && stats.data_dir.includes(':\\'); const isMac = stats.data_dir && stats.data_dir.includes('/usr/local/'); const logsEl = document.getElementById('footerLogs'); - if (isWin) { - document.getElementById('footerLogsWrap').style.display = 'none'; - } else { - logsEl.textContent = isMac - ? '/usr/local/var/log/numa.log' - : 'journalctl -u numa -f'; - } + logsEl.textContent = isWin + ? stats.data_dir + '\\numa.log' + : isMac ? '/usr/local/var/log/numa.log' + : 'journalctl -u numa -f'; } // LAN status indicator @@ -1523,7 +1520,7 @@ setInterval(refresh, 2000);
Config: · Data: - · Logs: + · Logs:
Upstream: · DNSSEC: diff --git a/src/lib.rs b/src/lib.rs index 8bb28d6..a16568b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,14 +101,11 @@ where /// Linux root daemon: /var/lib/numa (FHS) — falls back to /usr/local/var/numa /// if a pre-v0.10.1 install already lives there. /// macOS root daemon: /usr/local/var/numa (Homebrew prefix) -/// Windows: %APPDATA%\numa +/// Windows: %PROGRAMDATA%\numa (same as data_dir — no per-user config on Windows) pub fn config_dir() -> std::path::PathBuf { #[cfg(windows)] { - std::path::PathBuf::from( - std::env::var("APPDATA").unwrap_or_else(|_| "C:\\ProgramData".into()), - ) - .join("numa") + data_dir() } #[cfg(not(windows))] { diff --git a/src/main.rs b/src/main.rs index b8893b3..34bf747 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,21 +4,32 @@ use numa::system_dns::{ }; fn main() -> numa::Result<()> { + // Handle CLI subcommands + let arg1 = std::env::args().nth(1).unwrap_or_default(); + + #[cfg(windows)] + if arg1 == "--service" { + // Running under SCM — stderr goes nowhere. Redirect logs to a file. + let log_path = numa::data_dir().join("numa.log"); + let log_file = std::fs::OpenOptions::new() + .create(true) + .append(true) + .open(&log_path) + .expect("failed to open log file"); + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")) + .format_timestamp_millis() + .target(env_logger::Target::Pipe(Box::new(log_file))) + .init(); + numa::windows_service::run_as_service() + .map_err(|e| format!("windows service dispatcher failed: {}", e))?; + return Ok(()); + } + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")) .format_timestamp_millis() .init(); - // Handle CLI subcommands - let arg1 = std::env::args().nth(1).unwrap_or_default(); match arg1.as_str() { - #[cfg(windows)] - "--service" => { - // Entry point used by Windows SCM (`sc create … binPath="numa.exe --service"`). - // Blocks until SCM sends Stop; never returns normally. - numa::windows_service::run_as_service() - .map_err(|e| format!("windows service dispatcher failed: {}", e))?; - return Ok(()); - } "install" => { eprintln!("\x1b[1;38;2;192;98;58mNuma\x1b[0m — installing\n"); return install_service().map_err(|e| e.into());