Crate systemd_journal_logger
source ·Expand description
A pure Rust log logger for the systemd journal.
Usage
Create a JournalLog
with JournalLog::default
and then use JournalLog::install
to
setup journal logging. Then configure the logging level and now you can use the standard macros
from the log
crate to send log messages to the systemd journal:
use log::{info, warn, error, LevelFilter};
use systemd_journal_logger::JournalLog;
JournalLog::default().install().unwrap();
log::set_max_level(LevelFilter::Info);
info!("hello log");
warn!("warning");
error!("oops");
In a service you can use connected_to_journal
to check whether
the standard output or error stream of the current process is directly
connected to the systemd journal (the default for services started by
systemd) and fall back to logging to standard error if that’s not the
case. Take a look at the systemd_service.rs example for details.
Journal fields
The journald logger always sets the following standard journal fields:
PRIORITY
: The log level mapped to a priority (see below).MESSAGE
: The formatted log message (seelog::Record::args()
).SYSLOG_PID
: The PID of the running process (seestd::process::id()
).CODE_FILE
: The filename the log message originates from (seelog::Record::file()
, only if present).CODE_LINE
: The line number the log message originates from (seelog::Record::line()
, only if present).
It also sets SYSLOG_IDENTIFIER
if non-empty (see JournalLog::with_syslog_identifier
and JournalLog::default
).
Additionally it also adds the following non-standard fields:
TARGET
: The target of the log record (seelog::Record::target()
).CODE_MODULE
: The module path of the log record (seelog::Record::module_path()
, only if present).
In addition to these fields the logger also adds all structures key-values (see log::Record::key_values
)
from each log record as journal fields, after converting the keys to uppercase letters and replacing invalid
characters with underscores.
You can also add custom fields to every log entry with JournalLog::with_extra_fields
and customize the
syslog identifier with JournalLog::with_syslog_identifier
:
use log::{info, warn, error, LevelFilter};
use systemd_journal_logger::JournalLog;
JournalLog::default()
.with_extra_fields(vec![("VERSION", env!("CARGO_PKG_VERSION"))])
.with_syslog_identifier("foo".to_string())
.install().unwrap();
log::set_max_level(LevelFilter::Info);
info!("this message has an extra VERSION field in the journal");
You can display these extra fields with journalctl --output=verbose
and extract them with any of the structured
output formats of journalctl
, e.g. journalctl --output=json
.
Log levels and priorities
The journal logger maps log::Level
to journal priorities as follows:
Level::Error
→libsystemd::logging::Priority::Error
Level::Warn
→libsystemd::logging::Priority::Warning
Level::Info
→libsystemd::logging::Priority::Notice
Level::Debug
→libsystemd::logging::Priority::Info
Level::Trace
→libsystemd::logging::Priority::Debug
Errors
This crate currently does not implement any kind of error handling for journal messages. In particular it will panic when sending a record to journald fails, e.g. if journald is not running. There are no plans to change this behaviour, give that journald is reliable in general.
To implement an alternative error handling behaviour define a custom log implementation around
journal_send
which sends a single log record to the journal.
Structs
- A systemd journal logger.
Functions
- Whether this process can be automatically upgraded to native journal logging.
- Create a syslog identifier from the current executable.
- Escape a
key
for use in a systemd journal field. - Send a single log record to the journal.