diff --git a/examples/syslog_friendly_format.rs b/examples/syslog_friendly_format.rs index 9809ab3f..eac74adc 100644 --- a/examples/syslog_friendly_format.rs +++ b/examples/syslog_friendly_format.rs @@ -1,24 +1,12 @@ -use std::io::Write; - fn main() { - match std::env::var("RUST_LOG_STYLE") { - Ok(s) if s == "SYSTEMD" => env_logger::builder() - .format(|buf, record| { - writeln!( - buf, - "<{}>{}: {}", - match record.level() { - log::Level::Error => 3, - log::Level::Warn => 4, - log::Level::Info => 6, - log::Level::Debug => 7, - log::Level::Trace => 7, - }, - record.target(), - record.args() - ) - }) - .init(), - _ => env_logger::init(), - }; + env_logger::builder() + .parse_default_env() + // While journald-logging is auto-detected, you can manually override it. + // Especially useful if you are using a different logging system. + //.format_syslog(true) + .init(); + + // Prints in a human readable way if run interactively, + // and in a syslog-compatible way if run as a systemd service. + log::info!("we are logging"); } diff --git a/src/fmt/mod.rs b/src/fmt/mod.rs index 398dab70..43a210f3 100644 --- a/src/fmt/mod.rs +++ b/src/fmt/mod.rs @@ -63,7 +63,6 @@ use std::io::prelude::Write; use std::rc::Rc; use std::{fmt, io, mem}; -#[cfg(feature = "color")] use log::Level; use log::Record; @@ -275,6 +274,28 @@ impl Display for StyledValue { #[cfg(not(feature = "color"))] type StyledValue = T; +struct SyslogFormatter; + +impl SyslogFormatter { + pub(crate) fn build(&mut self) -> FormatFn { + Box::new(|buf: &mut Formatter, record: &Record<'_>| { + writeln!( + buf, + "<{}>{}: {}", + match record.level() { + Level::Error => 3, + Level::Warn => 4, + Level::Info => 6, + Level::Debug => 7, + Level::Trace => 7, + }, + record.target(), + record.args() + ) + }) + } +} + /// A [custom format][crate::Builder::format] with settings for which fields to show pub struct ConfigurableFormat { // This format needs to work with any combination of crate features. diff --git a/src/logger.rs b/src/logger.rs index 1ecfcc84..3d777b38 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -40,6 +40,7 @@ pub struct Builder { writer: writer::Builder, format: fmt::Builder, built: bool, + is_syslog: bool, } impl Builder { @@ -160,6 +161,10 @@ impl Builder { self.parse_write_style(&s); } + if env.is_daemon() { + self.is_syslog = true; + } + self } @@ -336,6 +341,14 @@ impl Builder { self } + /// If set to true, format log messages in a Syslog-adapted format. + /// + /// Overrides the auto-detected value. + pub fn format_syslog(&mut self, syslog: bool) -> &mut Self { + self.is_syslog = syslog; + self + } + /// Set the format for structured key/value pairs in the log record /// /// With the default format, this function is called for each record and should format @@ -533,7 +546,11 @@ impl Builder { Logger { writer: self.writer.build(), filter: self.filter.build(), - format: self.format.build(), + format: if self.is_syslog { + fmt::SyslogFormatter.build() + } else { + self.format.build() + }, } } } @@ -820,6 +837,11 @@ impl<'a> Env<'a> { fn get_write_style(&self) -> Option { self.write_style.get() } + + fn is_daemon(&self) -> bool { + // journald detection + Var::new("JOURNAL_STREAM").get().is_some() + } } impl<'a, T> From for Env<'a>