diff --git a/Cargo.toml b/Cargo.toml index cacafab..1bce1e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,10 @@ version = "0.2.0" edition = "2021" description = "mini-udev workalike" +[features] +default = ["syslog"] +syslog = ["dep:syslog-tracing"] + [dependencies] anyhow = "1.0.95" bytes = "1.9.0" @@ -14,6 +18,7 @@ kobject-uevent = "0.2.0" mdev-parser = "0.1.1" netlink-sys = { version = "0.8.7", features = ["tokio_socket"] } nix = { version = "0.29.0", features = ["user", "fs"] } +syslog-tracing = { version = "0.3.1", optional = true } thiserror = "2.0.9" tokio = { version = "1.42.0", features = [ "macros", diff --git a/src/bin/mdev-coldplug.rs b/src/bin/mdev-coldplug.rs index 3513106..17d133b 100644 --- a/src/bin/mdev-coldplug.rs +++ b/src/bin/mdev-coldplug.rs @@ -17,15 +17,17 @@ struct Opt { } impl Opt { - fn setup_log(&self) -> anyhow::Result<()> { - setup_log(self.verbose) + fn setup_log(&self) { + use tracing_subscriber::{fmt, prelude::*}; + let fmt_layer = fmt::layer().with_target(false); + setup_log(self.verbose).with(fmt_layer).init(); } } fn main() -> anyhow::Result<()> { let opt = Opt::parse(); - opt.setup_log()?; + opt.setup_log(); let classdir = WalkDir::new(opt.sysfs_mount.join("class")) .follow_links(true) diff --git a/src/bin/mdev.rs b/src/bin/mdev.rs index 7d9a505..f1f28e8 100644 --- a/src/bin/mdev.rs +++ b/src/bin/mdev.rs @@ -254,15 +254,56 @@ impl Opt { } fn setup_log(&self) -> anyhow::Result<()> { + use tracing_subscriber::{fmt, prelude::*}; if self.daemon && !self.foreground && !self.syslog { return Ok(()); } + let registry = setup_log(self.verbose); + let fmt_layer = fmt::layer().with_target(false); + + let mdev_log = Path::new("/dev/mdev.log"); + let file_log = if mdev_log.is_file() { + let log = std::fs::OpenOptions::new().append(true).open(mdev_log)?; + let fmt_layer = fmt::layer() + .with_target(false) + .with_ansi(false) + .with_writer(log); + Some(fmt_layer) + } else { + None + }; + + let registry = registry.with(file_log); + if self.syslog { - todo!("Wire in syslog somehow"); + #[cfg(feature = "syslog")] + { + use std::ffi::CString; + use syslog_tracing::{Facility, Options, Syslog}; + // SAFETY: They are strings that do not contain a null byte + let identity = std::env::args() + .next() + .map_or_else(|| CString::new("mdev"), |name| CString::new(name)) + .unwrap(); + let syslog = Syslog::new(identity, Options::LOG_PID, Facility::Daemon).unwrap(); + let fmt_layer = fmt_layer + .with_level(false) + .without_time() + .with_writer(syslog); + + registry.with(fmt_layer).init(); + } + #[cfg(not(feature = "syslog"))] + { + registry.with(fmt_layer).init(); + warn!("They syslog feature is disabled"); + } + } else { + registry.with(fmt_layer).init(); } - setup_log(self.verbose) + Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index fdf6d40..676305c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ use futures_util::ready; use kobject_uevent::UEvent; use netlink_sys::{AsyncSocket, SocketAddr, TokioSocket}; use tokio::sync::mpsc; +use tracing_subscriber::{layer::Layered, prelude::*, EnvFilter, Registry}; pub mod rule; pub mod stream; @@ -196,12 +197,7 @@ mod tests { } } -pub fn setup_log(verbose: u8) -> anyhow::Result<()> { - use tracing_subscriber::prelude::*; - use tracing_subscriber::{fmt, EnvFilter}; - - let fmt_layer = fmt::layer().with_target(false); - +pub fn setup_log(verbose: u8) -> Layered { let filter_layer = EnvFilter::try_from_default_env().unwrap_or_else(|_| { if verbose < 1 { EnvFilter::new("info") @@ -212,10 +208,5 @@ pub fn setup_log(verbose: u8) -> anyhow::Result<()> { } }); - tracing_subscriber::registry() - .with(filter_layer) - .with(fmt_layer) - .init(); - - Ok(()) + tracing_subscriber::registry().with(filter_layer) }