Rust SDK for Linux systemd: control units/jobs over the system D-Bus (systemctl-like), run transient one-shot tasks, and query journald logs (default: pure Rust backend; optional: journalctl --output=json).
Runtime is Linux-only (systemd + system bus required). The crate is designed to compile on other
platforms, but most operations will fail with Error::BackendUnavailable.
- CD/agent: restart a service and wait for a clear outcome (success/failed/timeout)
- Troubleshooting: get unit status + a bounded slice of recent logs on failure
- Deployment tasks: run one-shot commands as transient units and collect exit status
- Exporters/monitoring: enumerate units and read structured properties (Unit/Service/Socket/Timer) over D-Bus
- Traditional deployments: generate/install systemd service unit files and manage drop-ins (feature=
config)
- systemd on the system bus (
org.freedesktop.systemd1) - async runtime backend (mutually exclusive):
- default:
rt-async-io(notokiodependency) - optional:
rt-tokio(tokio backend)
- default:
- journald backend:
- default: pure Rust journal reader (feature=
journal-sdjournal) - optional:
journalctlJSON backend (feature=journal-cli)
- default: pure Rust journal reader (feature=
- Permissions:
- Unit control typically requires root or PolicyKit authorization.
- Reading logs via
journalctlmay require root orsystemd-journalgroup membership.
- Default runtime:
rt-async-io - Optional runtime:
rt-tokio(mutually exclusive withrt-async-io) - Default:
journal-sdjournal(pure Rust journald backend, nojournalctlsubprocess) - Optional:
journal-cli(journald viajournalctl --output=json) - Optional:
config(systemd config: unit files + drop-ins) - Optional:
tasks(transient tasks viaStartTransientUnit) - Optional:
tracing(instrumentation viatracing) - Optional:
observe(watch unit failures via D-Bus signals) - Optional:
blocking(synchronous wrappers, driven by the selected runtime)
[dependencies]
unitbus = "0.1"To use the journalctl backend (JSON):
[dependencies]
unitbus = { version = "0.1", default-features = false, features = ["rt-async-io", "journal-cli"] }To use tokio runtime (recommended for tokio apps):
[dependencies]
unitbus = { version = "0.1", default-features = false, features = ["rt-tokio", "journal-sdjournal"] }use unitbus::{UnitBus, UnitStartMode};
async fn restart_nginx() -> Result<(), unitbus::Error> {
let bus = UnitBus::connect_system().await?;
let job = bus.units().restart("nginx", UnitStartMode::Replace).await?;
let outcome = job.wait(std::time::Duration::from_secs(30)).await?;
println!("{outcome:?}");
Ok(())
}examples/restart_and_wait.rsexamples/fetch_recent_logs.rsexamples/diagnose_on_failure.rsexamples/list_units_and_properties.rsexamples/render_service_unit.rsexamples/run_transient_task.rs(requires--features tasks)examples/observe_unit_failure.rs(requires--features observe)examples/blocking_restart_and_wait.rs(requires--features blocking)