feat: record-daemon logs to a file
This commit is contained in:
Generated
+21
@@ -2418,6 +2418,7 @@ dependencies = [
|
||||
"tokio-util",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
"uuid",
|
||||
"winapi 0.3.9",
|
||||
@@ -3074,6 +3075,12 @@ version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "symlink"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
@@ -3255,6 +3262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"num-conv",
|
||||
"powerfmt",
|
||||
"serde_core",
|
||||
@@ -3520,6 +3528,19 @@ dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-appender"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "050686193eb999b4bb3bc2acfa891a13da00f79734704c4b8b4ef1a10b368a3c"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"symlink",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.31"
|
||||
|
||||
@@ -34,6 +34,7 @@ anyhow = "1"
|
||||
# Logging
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
tracing-appender = "0.2"
|
||||
|
||||
# UUID for recording IDs
|
||||
uuid = { version = "1", features = ["v4", "serde"] }
|
||||
|
||||
@@ -42,6 +42,10 @@ struct Args {
|
||||
/// Socket path for IPC.
|
||||
#[arg(short, long)]
|
||||
socket: Option<std::path::PathBuf>,
|
||||
|
||||
/// Path to log file. If not specified, logs to stdout/stderr.
|
||||
#[arg(short, long, value_name = "PATH")]
|
||||
log_file: Option<std::path::PathBuf>,
|
||||
}
|
||||
|
||||
/// Main daemon structure.
|
||||
@@ -579,15 +583,49 @@ impl Daemon {
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize logging.
|
||||
fn init_logging(level: &str) {
|
||||
/// Initialize logging with optional file output.
|
||||
fn init_logging(level: &str, log_file: Option<&std::path::Path>) {
|
||||
let filter = tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(level));
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(filter)
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
if let Some(log_path) = log_file {
|
||||
// Ensure parent directory exists
|
||||
if let Some(parent) = log_path.parent() {
|
||||
let _ = std::fs::create_dir_all(parent);
|
||||
}
|
||||
|
||||
// Use file appender for logging
|
||||
let prefix = log_path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("daemon");
|
||||
|
||||
let file_appender = tracing_appender::rolling::RollingFileAppender::builder()
|
||||
.rotation(tracing_appender::rolling::Rotation::DAILY)
|
||||
.filename_prefix(prefix)
|
||||
.filename_suffix("log")
|
||||
.build(log_path.parent().unwrap_or(std::path::Path::new(".")))
|
||||
.expect("Failed to create log file appender");
|
||||
|
||||
let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
|
||||
|
||||
// Store the guard to prevent it from being dropped
|
||||
// We leak it intentionally to keep logging working for the daemon's lifetime
|
||||
std::mem::forget(_guard);
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(filter)
|
||||
.with(tracing_subscriber::fmt::layer().with_writer(non_blocking))
|
||||
.init();
|
||||
|
||||
eprintln!("Logging to file: {}", log_path.display());
|
||||
} else {
|
||||
// Log to stdout/stderr
|
||||
tracing_subscriber::registry()
|
||||
.with(filter)
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
}
|
||||
|
||||
// Set up panic hook to log panics
|
||||
std::panic::set_hook(Box::new(|panic_info| {
|
||||
@@ -614,7 +652,7 @@ async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
// Initialize logging
|
||||
init_logging(&args.log_level);
|
||||
init_logging(&args.log_level, args.log_file.as_deref());
|
||||
|
||||
info!("Record Daemon v{} starting", record_daemon::VERSION);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user