Skip to content

feat: Syslog-adapted formating and auto-detection #358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/custom_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn main() {
.write_style("MY_LOG_STYLE");

Builder::from_env(env)
.format(|buf, record| {
.build_with_format_fn(|buf, record| {
// We are reusing `anstyle` but there are `anstyle-*` crates to adapt it to your
// preferred styling crate.
let warn_style = buf.default_level_style(log::Level::Warn);
Expand All @@ -41,7 +41,8 @@ fn main() {
record.args()
)
})
.init();
.try_init()
.unwrap();
}

init_logger();
Expand Down
32 changes: 10 additions & 22 deletions examples/syslog_friendly_format.rs
Original file line number Diff line number Diff line change
@@ -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, but 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");
}
2 changes: 1 addition & 1 deletion src/fmt/humantime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ impl Formatter {
///
/// let mut builder = env_logger::Builder::new();
///
/// builder.format(|buf, record| {
/// builder.build_with_format_fn(|buf, record| {
/// let ts = buf.timestamp();
///
/// writeln!(buf, "{}: {}: {}", ts, record.level(), record.args())
Expand Down
70 changes: 33 additions & 37 deletions src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//!
//! # Formatting log records
//!
//! The format used to print log records can be customised using the [`Builder::format`]
//! The format used to print log records can be customised using the [`Builder::build_with_format_fn`]
//! method.
//!
//! Terminal styling is done through ANSI escape codes and will be adapted to the capabilities of
Expand All @@ -25,7 +25,7 @@
//!
//! let mut builder = env_logger::Builder::new();
//!
//! builder.format(|buf, record| {
//! builder.build_with_format_fn(|buf, record| {
//! writeln!(buf, "{}: {}",
//! record.level(),
//! record.args())
Expand Down Expand Up @@ -61,9 +61,8 @@ use std::cell::RefCell;
use std::fmt::Display;
use std::io::prelude::Write;
use std::rc::Rc;
use std::{fmt, io, mem};
use std::{fmt, io};

#[cfg(feature = "color")]
use log::Level;
use log::Record;

Expand Down Expand Up @@ -125,7 +124,7 @@ impl Default for TimestampPrecision {
///
/// let mut builder = env_logger::Builder::new();
///
/// builder.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()));
/// builder.build_with_format_fn(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()));
/// ```
///
/// [`Write`]: std::io::Write
Expand Down Expand Up @@ -215,38 +214,6 @@ where

pub(crate) type FormatFn = Box<dyn RecordFormat + Sync + Send>;

#[derive(Default)]
pub(crate) struct Builder {
pub(crate) default_format: ConfigurableFormat,
pub(crate) custom_format: Option<FormatFn>,
built: bool,
}

impl Builder {
/// Convert the format into a callable function.
///
/// If the `custom_format` is `Some`, then any `default_format` switches are ignored.
/// If the `custom_format` is `None`, then a default format is returned.
/// Any `default_format` switches set to `false` won't be written by the format.
pub(crate) fn build(&mut self) -> FormatFn {
assert!(!self.built, "attempt to re-use consumed builder");

let built = mem::replace(
self,
Builder {
built: true,
..Default::default()
},
);

if let Some(fmt) = built.custom_format {
fmt
} else {
Box::new(built.default_format)
}
}
}

#[cfg(feature = "color")]
type SubtleStyle = StyledValue<&'static str>;
#[cfg(not(feature = "color"))]
Expand Down Expand Up @@ -276,6 +243,28 @@ impl<T: Display> Display for StyledValue<T> {
#[cfg(not(feature = "color"))]
type StyledValue<T> = T;

pub 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.
Expand All @@ -291,6 +280,13 @@ pub struct ConfigurableFormat {
pub(crate) kv_format: Option<Box<KvFormatFn>>,
}

impl ConfigurableFormat {
/// Convert the format into a callable function.
pub(crate) fn build(&mut self) -> FormatFn {
Box::new(std::mem::take(self))
}
}

impl ConfigurableFormat {
/// Format the [`Record`] as configured for outputting
pub fn format(&self, formatter: &mut Formatter, record: &Record<'_>) -> io::Result<()> {
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,10 @@
//! use std::io::Write;
//!
//! env_logger::builder()
//! .format(|buf, record| {
//! .build_with_format_fn(|buf, record| {
//! writeln!(buf, "{}: {}", record.level(), record.args())
//! })
//! .init();
//! .try_init().unwrap();
//! ```
//!
//! See the [`fmt`] module for more details about custom formats.
Expand Down
Loading