Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Migrating from slog to rlg

slog was the first structured-logging library for Rust to gain traction. Its o!(...) context macro and Logger::new(root, o!(...)) inheritance model don’t have a direct rlg equivalent — rlg records are flat and self-contained.

Context inheritance

#![allow(unused)]
fn main() {
// slog
let root = slog::Logger::root(drain, o!("service" => "api"));
let child = root.new(o!("user_id" => user_id));
info!(child, "authenticated");

// rlg
Log::info("authenticated")
    .component("api")
    .with("user_id", user_id)
    .fire();
}

For a shared context, wrap the fluent calls in a helper:

#![allow(unused)]
fn main() {
fn service_log(msg: &str) -> Log {
    Log::info(msg).component("api")
}

service_log("authenticated")
    .with("user_id", user_id)
    .fire();
}

Async drain

slog-async runs a channel between call sites and the actual drain. rlg’s engine already does this — every Log::fire() pushes to an atomic ring buffer, and a background flusher thread drains it. No migration needed.

Level mapping

slogrlg
trace!Log::trace
debug!Log::debug
info!Log::info
warn!Log::warn
error!Log::error
crit!Log::critical

Setup

#![allow(unused)]
fn main() {
// slog
let drain = slog_async::Async::new(slog_json::Json::default(io::stdout()).fuse()).build().fuse();
let root = slog::Logger::root(drain, o!());

// rlg
let _guard = rlg::init().unwrap();
}