diff --git a/Cargo.lock b/Cargo.lock index 2b2111c9..b4cf5bd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1322,6 +1322,7 @@ dependencies = [ "sha2", "static_init", "structopt", + "syslog-tracing", "timeago", "tokio", "toml", @@ -3930,6 +3931,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "syslog-tracing" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "340b1540dcdb6b066bc2966e7974f977ab1a38f21b2be189014ffb0cc2405768" +dependencies = [ + "libc", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "system-configuration" version = "0.5.1" diff --git a/Cargo.nix b/Cargo.nix index 852e96bf..44cb23b5 100644 --- a/Cargo.nix +++ b/Cargo.nix @@ -34,7 +34,7 @@ args@{ ignoreLockHash, }: let - nixifiedLockHash = "b35dd31aa882ac6fc7105fb99a6681a4777ed269191cb0a8c8db843910748435"; + nixifiedLockHash = "1d6c837fe8357cbb1b231c1843bde1729c9864f05e5ae251be045450a0b592e3"; workspaceSrc = if args.workspaceSrc == null then ./. else args.workspaceSrc; currentLockHash = builtins.hashFile "sha256" (workspaceSrc + /Cargo.lock); lockHashIgnored = if ignoreLockHash @@ -1889,6 +1889,8 @@ in (lib.optional (rootFeatures' ? "garage/default" || rootFeatures' ? "garage/metrics" || rootFeatures' ? "garage/prometheus") "prometheus") (lib.optional (rootFeatures' ? "garage/default" || rootFeatures' ? "garage/sled") "sled") (lib.optional (rootFeatures' ? "garage/default" || rootFeatures' ? "garage/sqlite") "sqlite") + (lib.optional (rootFeatures' ? "garage/syslog") "syslog") + (lib.optional (rootFeatures' ? "garage/syslog" || rootFeatures' ? "garage/syslog-tracing") "syslog-tracing") (lib.optional (rootFeatures' ? "garage/system-libs") "system-libs") (lib.optional (rootFeatures' ? "garage/telemetry-otlp") "telemetry-otlp") ]; @@ -1921,6 +1923,7 @@ in serde = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".serde."1.0.196" { inherit profileName; }).out; serde_bytes = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".serde_bytes."0.11.14" { inherit profileName; }).out; structopt = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".structopt."0.3.26" { inherit profileName; }).out; + ${ if rootFeatures' ? "garage/syslog" || rootFeatures' ? "garage/syslog-tracing" then "syslog_tracing" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".syslog-tracing."0.3.0" { inherit profileName; }).out; timeago = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".timeago."0.4.2" { inherit profileName; }).out; tokio = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".tokio."1.36.0" { inherit profileName; }).out; toml = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".toml."0.8.10" { inherit profileName; }).out; @@ -5612,6 +5615,18 @@ in }; }); + "registry+https://github.com/rust-lang/crates.io-index".syslog-tracing."0.3.0" = overridableMkRustCrate (profileName: rec { + name = "syslog-tracing"; + version = "0.3.0"; + registry = "registry+https://github.com/rust-lang/crates.io-index"; + src = fetchCratesIo { inherit name version; sha256 = "340b1540dcdb6b066bc2966e7974f977ab1a38f21b2be189014ffb0cc2405768"; }; + dependencies = { + ${ if rootFeatures' ? "garage/syslog" || rootFeatures' ? "garage/syslog-tracing" then "libc" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".libc."0.2.153" { inherit profileName; }).out; + ${ if rootFeatures' ? "garage/syslog" || rootFeatures' ? "garage/syslog-tracing" then "tracing_core" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".tracing-core."0.1.32" { inherit profileName; }).out; + ${ if rootFeatures' ? "garage/syslog" || rootFeatures' ? "garage/syslog-tracing" then "tracing_subscriber" else null } = (rustPackages."registry+https://github.com/rust-lang/crates.io-index".tracing-subscriber."0.3.18" { inherit profileName; }).out; + }; + }); + "registry+https://github.com/rust-lang/crates.io-index".system-configuration."0.5.1" = overridableMkRustCrate (profileName: rec { name = "system-configuration"; version = "0.5.1"; diff --git a/Cargo.toml b/Cargo.toml index c6f6f963..d3bbb301 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,7 @@ kuska-handshake = { version = "0.2.0", features = ["default", "async_std"] } clap = { version = "4.1", features = ["derive", "env"] } pretty_env_logger = "0.5" structopt = { version = "0.3", default-features = false } +syslog-tracing = "0.3" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/nix/compile.nix b/nix/compile.nix index b276495d..fdb427f2 100644 --- a/nix/compile.nix +++ b/nix/compile.nix @@ -173,6 +173,7 @@ let "garage/kubernetes-discovery" "garage/metrics" "garage/telemetry-otlp" + "garage/syslog" ] else [ ])); diff --git a/src/garage/Cargo.toml b/src/garage/Cargo.toml index b022049c..52861853 100644 --- a/src/garage/Cargo.toml +++ b/src/garage/Cargo.toml @@ -58,6 +58,7 @@ opentelemetry.workspace = true opentelemetry-prometheus = { workspace = true, optional = true } opentelemetry-otlp = { workspace = true, optional = true } prometheus = { workspace = true, optional = true } +syslog-tracing = { workspace = true, optional = true } [dev-dependencies] aws-config.workspace = true @@ -97,6 +98,8 @@ kubernetes-discovery = [ "garage_rpc/kubernetes-discovery" ] metrics = [ "garage_api/metrics", "opentelemetry-prometheus", "prometheus" ] # Exporter for the OpenTelemetry Collector. telemetry-otlp = [ "opentelemetry-otlp" ] +# Logging to syslog +syslog = [ "syslog-tracing" ] # NOTE: bundled-libs and system-libs should be treat as mutually exclusive; # exactly one of them should be enabled. diff --git a/src/garage/main.rs b/src/garage/main.rs index e489fff0..3fe96338 100644 --- a/src/garage/main.rs +++ b/src/garage/main.rs @@ -140,17 +140,8 @@ async fn main() { let opt = Opt::from_clap(&Opt::clap().version(version.as_str()).get_matches()); // Initialize logging as well as other libraries used in Garage - if std::env::var("RUST_LOG").is_err() { - let default_log = match &opt.cmd { - Command::Server => "netapp=info,garage=info", - _ => "netapp=warn,garage=warn", - }; - std::env::set_var("RUST_LOG", default_log) - } - tracing_subscriber::fmt() - .with_writer(std::io::stderr) - .with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env()) - .init(); + init_logging(&opt); + sodiumoxide::init().expect("Unable to init sodiumoxide"); let res = match opt.cmd { @@ -173,6 +164,51 @@ async fn main() { } } +fn init_logging(opt: &Opt) { + if std::env::var("RUST_LOG").is_err() { + let default_log = match &opt.cmd { + Command::Server => "netapp=info,garage=info", + _ => "netapp=warn,garage=warn", + }; + std::env::set_var("RUST_LOG", default_log) + } + + let env_filter = tracing_subscriber::filter::EnvFilter::from_default_env(); + + #[cfg(feature = "syslog")] + if std::env::var("GARAGE_LOG_TO_SYSLOG") + .map(|x| x == "1" || x == "true") + .unwrap_or(false) + { + use std::ffi::CStr; + use syslog_tracing::{Facility, Options, Syslog}; + + let syslog = Syslog::new( + CStr::from_bytes_with_nul(b"garage\0").unwrap(), + Options::LOG_PID | Options::LOG_PERROR, + Facility::Daemon, + ) + .expect("Unable to init syslog"); + + tracing_subscriber::fmt() + .with_writer(syslog) + .with_env_filter(env_filter) + .with_ansi(false) // disable ANSI escape sequences (colours) + .with_file(false) + .with_level(false) + .without_time() + .compact() + .init(); + + return; + } + + tracing_subscriber::fmt() + .with_writer(std::io::stderr) + .with_env_filter(env_filter) + .init(); +} + async fn cli_command(opt: Opt) -> Result<(), Error> { let config = if (opt.secrets.rpc_secret.is_none() && opt.secrets.rpc_secret_file.is_none()) || opt.rpc_host.is_none()