tracing-systemd
A tracing-subscriber Layer that pretty-prints
span chains to stdout and (optionally) the systemd journal.
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}
What's new in 0.2
- No more
libsystemd-devbuild dependency. Journald support now goes through the officialtracing-journaldlayer (pure Rust, speaks the native journal socket protocol). - Robustness: every
.unwrap()removed; the layer never panics on degenerate span/field states. - More customizable:
Cow<'static, str>separators (so you can pass ownedStrings), pluggable [ColorTheme], optional timestamps, custom [Output] writers (great for tests). - Better defaults:
ColorMode::AutorespectsNO_COLORand TTY status out of the box. - Documented:
#![deny(missing_docs)], working doctests, docs.rs metadata, full migration table below. - Modern toolchain: edition 2024, MSRV 1.85,
#![forbid(unsafe_code)], clippy::pedantic clean.
Quick start
[]
= "0.1"
= "0.3"
= "0.2"
use info;
use *;
use SystemdLayer;
Features
| Feature | Default | Effect |
|---|---|---|
colors |
yes | ANSI color output via nu-ansi-term. |
journald |
no | Re-exports tracing-journald under tracing_systemd::journald. Pure Rust; no libsystemd-dev needed. |
json |
no | Pulls in serde_json (reserved for a future JSON output mode). |
Disable color output with default-features = false:
= { = "0.2", = false }
Logging to the journal
Two patterns, depending on how your binary is invoked.
Under a systemd unit (most common): the unit's stdout/stderr is already routed to the
journal. Just use SystemdLayer::stdout() with the level prefix on (it's the default), and
journalctl will pick up the syslog priority from the <3>–<7> markers.
# use *;
# use SystemdLayer;
registry
.with // level prefix `<5>` etc. is emitted by default
.init;
Outside a unit, e.g. running locally for development: enable the journald feature and
attach the dedicated layer.
use *;
use SystemdLayer;
let journald = layer_with_identifier.ok;
registry
.with // pretty for humans
.with // structured fields into the journal
.init;
Option<Layer> implements Layer<S>, so passing None (when journald isn't reachable)
cleanly disables that arm without an if let.
Filter your entries with journalctl -t my-app.
Customization
Every separator and bracket is overridable via the builder; they accept anything that
implements Into<Cow<'static, str>>, so &'static str and String both 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, write to any io::Write:
use ;
use ;
let buf = new;
let layer = stdout
.with_output;
Migration from 0.1
The crate has 2,300+ downloads on 0.1 — here's the explicit method-name mapping.
| 0.1 method | 0.2 equivalent |
|---|---|
SystemdLayer::new() |
SystemdLayer::stdout() |
with_target(b) |
with_target(b) (unchanged) |
with_thread_ids(b) |
with_thread_ids(b) (unchanged) |
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) / use_color(false) |
with_color_mode(ColorMode::Always / Never) |
use_sd_journal(true) |
Add tracing_systemd::journald::layer()? as a separate layer (requires journald feature). |
| (N/A) | with_timestamps, with_timestamp_format, with_color_theme, with_output (new) |
Other behavior changes:
- The default for color output is now
ColorMode::Auto(was: always on under thecoloredfeature). Passwith_color_mode(ColorMode::Always)for the old behavior. coloredfeature renamed tocolors.sd-journalfeature removed; usejournald(which pulls intracing-journaldinstead).- The old runtime
use_sd_journal(false)toggle is gone — pick the right layer at construction time.
MSRV
Tracing-systemd 0.2 requires Rust 1.85 (edition 2024). Bumping the MSRV is a minor version bump going forward.