Skip to content
20 changes: 19 additions & 1 deletion tracing-journald/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

#[cfg(unix)]
use std::os::unix::net::UnixDatagram;
use std::{fmt, io, io::Write};
use std::{collections::HashMap, fmt, io, io::Write};

use tracing_core::{
event::Event,
Expand Down Expand Up @@ -85,6 +85,7 @@ pub struct Subscriber {
socket: UnixDatagram,
field_prefix: Option<String>,
syslog_identifier: String,
additional_fields: HashMap<String, String>,
}

#[cfg(unix)]
Expand All @@ -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),
additional_fields: HashMap::new(),
};
// 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.
Expand Down Expand Up @@ -150,6 +152,18 @@ impl Subscriber {
self
}

/// Adds a field that will get be passed to journald with every log entry.
///
/// This can for example be used to configure the syslog 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.
pub fn with_journal_field(mut self, key: String, value: String) -> Self {
self.additional_fields.insert(key, value);
self
}

/// Returns the syslog identifier in use.
pub fn syslog_identifier(&self) -> &str {
&self.syslog_identifier
Expand Down Expand Up @@ -258,6 +272,10 @@ where
write!(buf, "{}", self.syslog_identifier).unwrap()
});

for (name, value) in &self.additional_fields {
put_field_length_encoded(&mut buf, name, |buf| write!(buf, "{}", value).unwrap())
}

event.record(&mut EventVisitor::new(
&mut buf,
self.field_prefix.as_deref(),
Expand Down
21 changes: 21 additions & 0 deletions tracing-journald/tests/journal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,27 @@ fn simple_metadata() {
});
}

#[test]
fn journal_fields() {
let sub = Subscriber::new()
.unwrap()
.with_field_prefix(None)
.with_journal_field("SYSLOG_FACILITY".to_string(), "17".to_string())
.with_journal_field("DOCUMENTATION".to_string(), "aBc".to_string());
with_journald_subscriber(sub, || {
info!(test.name = "journal_fields", "Hello World");

let message = retry_read_one_line_from_journal("journal_fields");
assert_eq!(message["MESSAGE"], "Hello World");
assert_eq!(message["PRIORITY"], "5");
assert_eq!(message["TARGET"], "journal");
assert_eq!(message["SYSLOG_FACILITY"], "17");
assert_eq!(message["DOCUMENTATION"], "aBc");
assert!(message["CODE_FILE"].as_text().is_some());
assert!(message["CODE_LINE"].as_text().is_some());
});
}

#[test]
fn span_metadata() {
with_journald(|| {
Expand Down