diff --git a/Cargo.lock b/Cargo.lock index 9efc27b..60e2262 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1258,6 +1258,7 @@ dependencies = [ "tokio-tun", "tokio-util", "tracing", + "tracing-logfmt", "tracing-subscriber", "tun", "wintun 0.4.0", @@ -2457,9 +2458,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", + "itoa", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -2468,6 +2471,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2659,6 +2671,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-logfmt" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22b8e455f6caa5212a102ec530bf86b8dc5a4c536299bffd84b238fed9119be7" +dependencies = [ + "time", + "tracing", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "tracing-oslog" version = "0.1.2" diff --git a/mycelium/Cargo.toml b/mycelium/Cargo.toml index 3ee4b69..336480c 100644 --- a/mycelium/Cargo.toml +++ b/mycelium/Cargo.toml @@ -28,6 +28,7 @@ x25519-dalek = { version = "2.0.1", features = ["getrandom", "static_secrets"] } aes-gcm = "0.10.3" tracing = { version = "0.1.40", features = ["release_max_level_debug"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +tracing-logfmt = { version = "0.3.4" } faster-hex = "0.9.0" tokio-stream = { version = "0.1.15", features = ["sync"] } left-right = "0.11.5" diff --git a/myceliumd-private/Cargo.lock b/myceliumd-private/Cargo.lock index c2756c8..8fd1e47 100644 --- a/myceliumd-private/Cargo.lock +++ b/myceliumd-private/Cargo.lock @@ -1188,6 +1188,7 @@ dependencies = [ "tokio-tun", "tokio-util", "tracing", + "tracing-logfmt", "tracing-subscriber", "tun", "wintun 0.4.0", @@ -1250,6 +1251,7 @@ dependencies = [ "serde_json", "tokio", "tracing", + "tracing-logfmt", "tracing-subscriber", ] @@ -2337,10 +2339,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -2349,6 +2353,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2529,6 +2543,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-logfmt" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22b8e455f6caa5212a102ec530bf86b8dc5a4c536299bffd84b238fed9119be7" +dependencies = [ + "time", + "tracing", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "tracing-subscriber" version = "0.3.18" diff --git a/myceliumd-private/Cargo.toml b/myceliumd-private/Cargo.toml index 2130f1e..8803492 100644 --- a/myceliumd-private/Cargo.toml +++ b/myceliumd-private/Cargo.toml @@ -16,6 +16,7 @@ path = "src/main.rs" [dependencies] clap = { version = "4.5.8", features = ["derive"] } tracing = { version = "0.1.40", features = ["release_max_level_debug"] } +tracing-logfmt = "0.3.4" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } mycelium = { path = "../mycelium", features = ["private-network", "message"] } mycelium-metrics = { path = "../mycelium-metrics", features = ["prometheus"] } diff --git a/myceliumd-private/src/main.rs b/myceliumd-private/src/main.rs index 4e45f46..89af8a6 100644 --- a/myceliumd-private/src/main.rs +++ b/myceliumd-private/src/main.rs @@ -6,6 +6,7 @@ use std::{ net::{IpAddr, SocketAddr}, path::PathBuf, }; +use std::{fmt::Display, str::FromStr}; use clap::{Args, Parser, Subcommand}; use tokio::fs::File; @@ -19,7 +20,7 @@ use mycelium::endpoint::Endpoint; use mycelium::{crypto, Node}; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -use tracing_subscriber::{EnvFilter, Layer}; +use tracing_subscriber::EnvFilter; /// The default port on the underlay to listen on for incoming TCP connections. const DEFAULT_TCP_LISTEN_PORT: u16 = 9651; @@ -40,6 +41,38 @@ const TUN_NAME: &str = "tun0"; #[cfg(target_os = "macos")] const TUN_NAME: &str = "utun3"; +/// The logging formats that can be selected. +#[derive(Clone, PartialEq, Eq)] +enum LoggingFormat { + Compact, + Logfmt, +} + +impl Display for LoggingFormat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + LoggingFormat::Compact => "compact", + LoggingFormat::Logfmt => "logfmt", + } + ) + } +} + +impl FromStr for LoggingFormat { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + Ok(match s { + "compact" => LoggingFormat::Compact, + "logfmt" => LoggingFormat::Logfmt, + _ => return Err("invalid logging format"), + }) + } +} + #[derive(Parser)] #[command(version)] struct Cli { @@ -56,6 +89,10 @@ struct Cli { #[arg(long = "silent", default_value_t = false)] silent: bool, + /// The logging format to use. `logfmt` and `compact` is supported. + #[arg(long = "log-format", default_value_t = LoggingFormat::Compact)] + logging_format: LoggingFormat, + #[clap(flatten)] node_args: NodeArguments, @@ -262,13 +299,16 @@ async fn main() -> Result<(), Box> { tracing_subscriber::registry() .with( - tracing_subscriber::fmt::Layer::new().compact().with_filter( - EnvFilter::builder() - .with_default_directive(level.into()) - .from_env() - .expect("invalid RUST_LOG"), - ), + EnvFilter::builder() + .with_default_directive(level.into()) + .from_env() + .expect("invalid RUST_LOG"), ) + .with( + (cli.logging_format == LoggingFormat::Compact) + .then(|| tracing_subscriber::fmt::Layer::new().compact()), + ) + .with((cli.logging_format == LoggingFormat::Logfmt).then(|| tracing_logfmt::layer())) .init(); let key_path = cli diff --git a/myceliumd/Cargo.lock b/myceliumd/Cargo.lock index d63a163..484b0d5 100644 --- a/myceliumd/Cargo.lock +++ b/myceliumd/Cargo.lock @@ -1171,6 +1171,7 @@ dependencies = [ "tokio-tun", "tokio-util", "tracing", + "tracing-logfmt", "tracing-subscriber", "tun", "wintun 0.4.0", @@ -1235,6 +1236,7 @@ dependencies = [ "serde_json", "tokio", "tracing", + "tracing-logfmt", "tracing-subscriber", "urlencoding", ] @@ -2269,10 +2271,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", "time-core", + "time-macros", ] [[package]] @@ -2281,6 +2285,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2449,6 +2463,18 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-logfmt" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22b8e455f6caa5212a102ec530bf86b8dc5a4c536299bffd84b238fed9119be7" +dependencies = [ + "time", + "tracing", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "tracing-subscriber" version = "0.3.18" diff --git a/myceliumd/Cargo.toml b/myceliumd/Cargo.toml index 613fdc6..a81cf8f 100644 --- a/myceliumd/Cargo.toml +++ b/myceliumd/Cargo.toml @@ -14,6 +14,7 @@ path = "src/main.rs" [dependencies] clap = { version = "4.5.8", features = ["derive"] } tracing = { version = "0.1.40", features = ["release_max_level_debug"] } +tracing-logfmt = "0.3.4" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } mycelium = { path = "../mycelium", features = ["message"] } mycelium-metrics = { path = "../mycelium-metrics", features = ["prometheus"] } diff --git a/myceliumd/src/main.rs b/myceliumd/src/main.rs index ede85a9..cc894d4 100644 --- a/myceliumd/src/main.rs +++ b/myceliumd/src/main.rs @@ -6,6 +6,7 @@ use std::{ net::{IpAddr, SocketAddr}, path::PathBuf, }; +use std::{fmt::Display, str::FromStr}; use clap::{Args, Parser, Subcommand}; use tokio::fs::File; @@ -19,7 +20,7 @@ use mycelium::endpoint::Endpoint; use mycelium::{crypto, Node}; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; -use tracing_subscriber::{EnvFilter, Layer}; +use tracing_subscriber::EnvFilter; /// The default port on the underlay to listen on for incoming TCP connections. const DEFAULT_TCP_LISTEN_PORT: u16 = 9651; @@ -40,6 +41,38 @@ const TUN_NAME: &str = "tun0"; #[cfg(target_os = "macos")] const TUN_NAME: &str = "utun3"; +/// The logging formats that can be selected. +#[derive(Clone, PartialEq, Eq)] +enum LoggingFormat { + Compact, + Logfmt, +} + +impl Display for LoggingFormat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + LoggingFormat::Compact => "compact", + LoggingFormat::Logfmt => "logfmt", + } + ) + } +} + +impl FromStr for LoggingFormat { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + Ok(match s { + "compact" => LoggingFormat::Compact, + "logfmt" => LoggingFormat::Logfmt, + _ => return Err("invalid logging format"), + }) + } +} + #[derive(Parser)] #[command(version)] struct Cli { @@ -56,6 +89,10 @@ struct Cli { #[arg(long = "silent", default_value_t = false)] silent: bool, + /// The logging format to use. `logfmt` and `compact` is supported. + #[arg(long = "log-format", default_value_t = LoggingFormat::Compact)] + logging_format: LoggingFormat, + #[clap(flatten)] node_args: NodeArguments, @@ -245,13 +282,16 @@ async fn main() -> Result<(), Box> { tracing_subscriber::registry() .with( - tracing_subscriber::fmt::Layer::new().compact().with_filter( - EnvFilter::builder() - .with_default_directive(level.into()) - .from_env() - .expect("invalid RUST_LOG"), - ), + EnvFilter::builder() + .with_default_directive(level.into()) + .from_env() + .expect("invalid RUST_LOG"), ) + .with( + (cli.logging_format == LoggingFormat::Compact) + .then(|| tracing_subscriber::fmt::Layer::new().compact()), + ) + .with((cli.logging_format == LoggingFormat::Logfmt).then(|| tracing_logfmt::layer())) .init(); let key_path = cli