tracing-systemd
A tracing-subscriber layer that prints span chains
to stdout in a format that's easy to read locally and easy to ingest into the systemd
journal when run under a unit.
INFO [1] my_app::request(method: "GET", path: "/api")::handler(): served in 4ms
WARN [1] my_app::request(method: "POST", path: "/api")::handler(): retrying: {attempt: 2}
Usage
[]
= "0.1"
= "0.3"
= "0.2"
use info;
use *;
use SystemdLayer;
See examples/ for more.
Features
| Feature | Default | Effect |
|---|---|---|
colors |
yes | ANSI color output via nu-ansi-term. |
journald |
no | Re-exports tracing-journald under tracing_systemd::journald. |
json |
no | Pulls in serde_json (reserved for a future JSON output mode). |
To turn off color output:
= { = "0.2", = false }
Logging to the journal
There are two ways to get logs into journald, depending on how the binary is started.
If your binary runs under a systemd unit, its stdout/stderr is already piped to the
journal. The default SystemdLayer::stdout() emits the <3>–<7> syslog priority
prefix that journalctl uses to assign levels, so you don't need anything else:
# use *;
# use SystemdLayer;
registry
.with
.init;
If you want structured fields in the journal, or you're running outside a unit, enable
the journald feature and add the dedicated layer alongside the stdout one:
use *;
use SystemdLayer;
let journald = layer_with_identifier.ok;
registry
.with
.with
.init;
Option<Layer> implements Layer<S>, so a None (when journald isn't reachable)
just becomes a no-op without an if let.
Filter entries with journalctl -t my-app.
Customization
All separators, brackets, and prefixes are overridable on the builder. They take
anything that's Into<Cow<'static, str>>, so both &'static str and String work.
use ;
use ;
let layer = stdout
.with_target
.with_thread_ids
.with_timestamp_format
.with_function_bracket_left
.with_function_bracket_right
.with_arguments_equality
.with_color_mode
.with_color_theme;
For tests, redirect output to any io::Write:
use ;
use ;
let buf = new;
let layer = stdout
.with_output;
Migrating from 0.1
| 0.1 | 0.2 |
|---|---|
SystemdLayer::new() |
SystemdLayer::stdout() |
separate_spans_with(s) |
with_span_separator(s) |
separate_message_with(s) |
with_message_separator(s) |
level_separator(s) |
with_level_separator(s) |
function_bracket_left(s) |
with_function_bracket_left(s) |
function_bracket_right(s) |
with_function_bracket_right(s) |
arguments_equality(s) |
with_arguments_equality(s) |
arguments_separator(s) |
with_arguments_separator(s) |
thread_id_prefix(s) |
with_thread_id_prefix(s) |
thread_id_suffix(s) |
with_thread_id_suffix(s) |
use_level_prefix(b) |
with_level_prefix(b) |
use_color(true/false) |
with_color_mode(ColorMode::Always / Never) |
use_sd_journal(true) |
Add tracing_systemd::journald::layer()? as a separate layer (needs journald feature). |
with_target and with_thread_ids are unchanged. with_timestamps,
with_timestamp_format, with_color_theme, and with_output are new.
Other things that changed:
- The default for color is now
ColorMode::Auto(respectsNO_COLORand TTY status). PassColorMode::Alwaysfor the old behavior. - The
coloredfeature was renamed tocolors. - The
sd-journalfeature is gone; usejournald, which goes throughtracing-journald(pure Rust, nolibsystemd-dev). - The runtime
use_sd_journal(false)toggle is gone. Pick the layer at construction time instead.
MSRV
Rust 1.85 (edition 2024). MSRV bumps are minor version bumps.