Skip to content

Commit

Permalink
logging: split journal stream checks from protocol upgrading
Browse files Browse the repository at this point in the history
This introduces two new helpers to separately check whether stdout
or stderr are connected to a journal stream.
More importantly, it changes `connected_to_journal()` behavior to
only check stderr.

These changes are meant to logically split the `$JOURNAL_STREAM`
helpers from protocol upgrading. The former concern low-level
settings which can be set on stdout and stderr separately. The
latter instead is an high-level concept which assumes that all the
logging happens on stderr.
  • Loading branch information
lucab committed Nov 4, 2022
1 parent 8ada6e3 commit c51fdd8
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions src/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,32 +308,65 @@ impl JournalStream {
}
}

/// Whether this process is directly connected to the journal.
/// Whether this process stdout is directly streamed to journal.
///
/// Inspects the `$JOURNAL_STREAM` environment variable and compares the device and inode
/// numbers in this variable against the stdout and stderr file descriptors.
/// numbers in this variable against the stdout file descriptor.
///
/// Return `true` if either stream matches the device and inode numbers in `$JOURNAL_STREAM`,
/// and `false` otherwise (or in case of any IO error).
/// Return `true` if they match, and `false` otherwise (or in case of any IO error).
///
/// Systemd sets `$JOURNAL_STREAM` to the device and inode numbers of the standard output
/// or standard error streams of the current process if either of these streams is connected
/// to the systemd journal.
/// Systemd sets `$JOURNAL_STREAM` if any of stdout or stderr of the current process is
/// connected to systemd journal.
///
/// Systemd explicitly recommends that services check this variable to upgrade their logging
/// to the native systemd journal protocol.
/// See section “Environment Variables Set or Propagated by the Service Manager” in
/// [systemd.exec(5)][1] for more information.
///
/// [1]: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment%20Variables%20Set%20or%20Propagated%20by%20the%20Service%20Manager
pub fn stdout_is_journal_stream() -> bool {
JournalStream::from_env_default().map_or(false, |env_stream| {
JournalStream::from_fd(io::stdout()).map_or(false, |o| o == env_stream)
})
}

/// Whether this process stderr is directly streamed to journal.
///
/// Inspects the `$JOURNAL_STREAM` environment variable and compares the device and inode
/// numbers in this variable against the stderr file descriptor.
///
/// Return `true` if they match, and `false` otherwise (or in case of any IO error).
///
/// Systemd sets `$JOURNAL_STREAM` if any of stdout or stderr of the current process is
/// connected to systemd journal.
///
/// See section “Environment Variables Set or Propagated by the Service Manager” in
/// [systemd.exec(5)][1] for more information.
///
/// [1]: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment%20Variables%20Set%20or%20Propagated%20by%20the%20Service%20Manager
pub fn connected_to_journal() -> bool {
pub fn stderr_is_journal_stream() -> bool {
JournalStream::from_env_default().map_or(false, |env_stream| {
JournalStream::from_fd(io::stderr()).map_or(false, |e| e == env_stream)
|| JournalStream::from_fd(io::stdout()).map_or(false, |o| o == env_stream)
JournalStream::from_fd(io::stderr()).map_or(false, |o| o == env_stream)
})
}

/// Whether this process can be automatically upgraded to native journal logging.
///
/// Inspects the `$JOURNAL_STREAM` environment variable and compares the device and inode
/// numbers in this variable against the stderr file descriptor.
///
/// Return `true` if they match, and `false` otherwise (or in case of any IO error).
/// This is effectively equivalent to [stderr_is_journal_stream].
///
/// For services normally logging to stderr but also supporting systemd-style structured
/// logging, it is recommended to perform this check and then possibly upgrade to the
/// native systemd journal protocol.
///
/// See section “Automatic Protocol Upgrading” in [systemd documentation][1] for more information.
///
/// [1]: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/#automatic-protocol-upgrading
pub fn connected_to_journal() -> bool {
stderr_is_journal_stream()
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit c51fdd8

Please sign in to comment.