From 50bade0cee908493aad8db068da6862aa7047006 Mon Sep 17 00:00:00 2001 From: Ossi Herrala Date: Thu, 12 Jan 2023 13:12:30 +0200 Subject: [PATCH] journald: add support for specifying syslog facility The syslog facility is optional and if it is not specified, it is not included in JournalD message. The SyslogFacility enum contains all the fields specified in syslog(3) for facility and numbers are mapped using libc's definition. --- tracing-journald/src/lib.rs | 40 +++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/tracing-journald/src/lib.rs b/tracing-journald/src/lib.rs index 237a0de647..0bb0ff2aac 100644 --- a/tracing-journald/src/lib.rs +++ b/tracing-journald/src/lib.rs @@ -85,6 +85,7 @@ pub struct Subscriber { socket: UnixDatagram, field_prefix: Option, syslog_identifier: String, + syslog_facility: Option, } #[cfg(unix)] @@ -109,6 +110,7 @@ impl Subscriber { .map(|n| n.to_string_lossy().into_owned()) // If we fail to get the name of the current executable fall back to an empty string. .unwrap_or_else(String::new), + syslog_facility: None, }; // Check that we can talk to journald, by sending empty payload which journald discards. // However if the socket didn't exist or if none listened we'd get an error here. @@ -131,8 +133,8 @@ impl Subscriber { /// Sets the syslog identifier for this logger. /// - /// The syslog identifier comes from the classic syslog interface (`openlog()` - /// and `syslog()`) and tags log entries with a given identifier. + /// The syslog identifier comes from the classic syslog interface (`openlog(3)` + /// and `syslog(3)`) and tags log entries with a given identifier. /// Systemd exposes it in the `SYSLOG_IDENTIFIER` journal field, and allows /// filtering log messages by syslog identifier with `journalctl -t`. /// Unlike the unit (`journalctl -u`) this field is not trusted, i.e. applications @@ -151,10 +153,39 @@ impl Subscriber { } /// Returns the syslog identifier in use. + /// + /// A syslog identifier can be set using [`Subscriber::with_syslog_identifier`]. pub fn syslog_identifier(&self) -> &str { &self.syslog_identifier } + /// Sets the syslog facility for this logger. + /// + /// The syslog facility comes from the classic syslog interface (`openlog(3)` + /// and `syslog(3)`). In syslog, the facility argument is used to specify + /// what type of program is logging the message. This lets the configuration + /// file specify that messages from different facilities will be handled + /// differently. Systemd exposes it in the `SYSLOG_FACILITY` journal field, + /// and allows filtering log messages by syslog facility with `journalctl + /// --facility`. + /// + /// See [Journal Fields](https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html) + /// and [journalctl](https://www.freedesktop.org/software/systemd/man/journalctl.html) + /// for more information. + /// + /// If not set, this field is left out. + pub fn with_syslog_facility(mut self, facility: libc::c_int) -> Self { + self.syslog_facility = Some(facility); + self + } + + /// Returns the syslog facility in use. + /// + /// A syslog facility can be set using [`Subscriber::with_syslog_facility`]. + pub fn syslog_facility(&self) -> Option { + self.syslog_facility + } + #[cfg(not(unix))] fn send_payload(&self, _opayload: &[u8]) -> io::Result<()> { Err(io::Error::new( @@ -257,6 +288,11 @@ where put_field_length_encoded(&mut buf, "SYSLOG_IDENTIFIER", |buf| { write!(buf, "{}", self.syslog_identifier).unwrap() }); + if let Some(facility) = self.syslog_facility { + // libc definitions are bitshifted left by 3, but journald uses + // values without bitshift. + writeln!(buf, "SYSLOG_FACILITY={}", facility >> 3).unwrap(); + } event.record(&mut EventVisitor::new( &mut buf,