mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-09-29 22:10:38 +00:00
journald: allow custom journal fields (#2708)
It's currently not possible to customize how messages will get send to journald. This became apparent in #2425, where first a specific API got designed, but then it was decided that users should not get restricted in only a subset of fields, but should be able to simply choose by themselves what fields get set with what values. So in a sense, this is the successor/rework of #2425. Allow custom fields to be set in tracing-journald. - [x] How should we deal with fields that also get supplied by other options? For example, setting `SYSLOG_IDENTIFIER` here and also setting `.with_syslog_identifier()` will send said field twice, potentially with differing values. Is that a problem? - Answer: No, this is not a problem. Closes #2425
This commit is contained in:
parent
b8180dd886
commit
7666f6c453
@ -83,6 +83,7 @@ pub struct Layer {
|
||||
socket: UnixDatagram,
|
||||
field_prefix: Option<String>,
|
||||
syslog_identifier: String,
|
||||
additional_fields: Vec<u8>,
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
@ -107,6 +108,7 @@ impl Layer {
|
||||
.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: Vec::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.
|
||||
@ -148,6 +150,40 @@ impl Layer {
|
||||
self
|
||||
}
|
||||
|
||||
/// Adds fields that will get be passed to journald with every log entry.
|
||||
///
|
||||
/// The input values of this function are interpreted as `(field, value)` pairs.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Fields specified using this method will be added to the journald
|
||||
/// message alongside fields generated from the event's fields, its
|
||||
/// metadata, and the span context. If the name of a field provided using
|
||||
/// this method is the same as the name of a field generated by the
|
||||
/// layer, both fields will be sent to journald.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use tracing_journald::Layer;
|
||||
/// let layer = Layer::new()
|
||||
/// .unwrap()
|
||||
/// .with_custom_fields([("SYSLOG_FACILITY", "17")]);
|
||||
/// ```
|
||||
///
|
||||
pub fn with_custom_fields<T: AsRef<str>, U: AsRef<[u8]>>(
|
||||
mut self,
|
||||
fields: impl IntoIterator<Item = (T, U)>,
|
||||
) -> Self {
|
||||
for (name, value) in fields {
|
||||
put_field_length_encoded(&mut self.additional_fields, name.as_ref(), |buf| {
|
||||
buf.extend_from_slice(value.as_ref())
|
||||
})
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns the syslog identifier in use.
|
||||
pub fn syslog_identifier(&self) -> &str {
|
||||
&self.syslog_identifier
|
||||
@ -255,6 +291,7 @@ where
|
||||
put_field_length_encoded(&mut buf, "SYSLOG_IDENTIFIER", |buf| {
|
||||
write!(buf, "{}", self.syslog_identifier).unwrap()
|
||||
});
|
||||
buf.extend_from_slice(&self.additional_fields);
|
||||
|
||||
event.record(&mut EventVisitor::new(
|
||||
&mut buf,
|
||||
|
@ -238,6 +238,28 @@ fn simple_metadata() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn journal_fields() {
|
||||
let sub = Layer::new()
|
||||
.unwrap()
|
||||
.with_field_prefix(None)
|
||||
.with_custom_fields([("SYSLOG_FACILITY", "17")])
|
||||
.with_custom_fields([("ABC", "dEf"), ("XYZ", "123")]);
|
||||
with_journald_layer(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["ABC"], "dEf");
|
||||
assert_eq!(message["XYZ"], "123");
|
||||
assert!(message["CODE_FILE"].as_text().is_some());
|
||||
assert!(message["CODE_LINE"].as_text().is_some());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn span_metadata() {
|
||||
with_journald(|| {
|
||||
|
Loading…
x
Reference in New Issue
Block a user