slog-stdlog

Two-way bridge between Rust's log crate and slog for unified structured logging.

Library
Cargo
v4.1.1
12stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
29/100Needs Attention
Development Activity0
Maintenance20
Community24
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture62
Code Quality55
Innovation65
Learning Curve55

slog-stdlog is a compatibility adapter that lets slog-based applications and log-based libraries coexist in the same Rust binary. It provides two-way bridging: forwarding all log crate macro calls (info!, error!, etc.) into a global slog::Logger via slog-scope, and a StdLog Drain that redirects slog Records back out through the log crate’s backend.

This matters when an application standardizes on slog for structured, context-aware logging but depends on third-party crates that only emit through the standard log facade — rather than running two disconnected logging pipelines, slog-stdlog lets everything funnel through one logger, in whichever direction the project needs.

What You Get

  • init() / init_with_level() functions that register slog-stdlog as the global log backend, forwarding every log! macro call to the current slog_scope::logger()
  • A StdLog slog::Drain that takes slog Records and re-emits them through the log crate, formatting key-value pairs into the message string
  • An optional kv_unstable Cargo feature that forwards structured key-value pairs from log’s unstable kv API into slog’s typed Serializer
  • A zero-cost pass-through design — no buffering, extra threads, or custom formatting; all actual output is handled by whatever slog Drain or log backend is configured downstream

Common Use Cases

  • Adopting slog in an application that depends on crates only instrumented with the log facade, capturing their output through a single structured slog pipeline
  • Migrating an existing log-based codebase to slog incrementally, keeping both logging call styles working during the transition
  • Exposing a slog-based library’s output to consumers who have only wired up a log-compatible logger such as env_logger

Under The Hood

Architecture slog-stdlog is a thin two-way bridge crate with almost no architecture of its own: a private zero-sized Logger struct implements log::Log and forwards every call into slog_scope::with_logger(), while a public StdLog struct implements slog::Drain and forwards slog::Records back out through log::logger(). Both directions convert between log::Level and slog::Level via straightforward match arms (log_to_slog_level in lib.rs, and an inline match inside StdLog::log), and the sloglog direction lazily formats key-value pairs on demand with the LazyLogString wrapper and a custom Ksv (key-separator-value) slog::Serializer, so formatting cost is paid only if the underlying log backend actually consumes the message. There is no buffering, no async, and no owned state beyond the two marker structs — every actual write is delegated to whichever log::Log implementation or slog::Drain the caller has installed.

Tech Stack The crate is intentionally minimal: three runtime dependencies (slog ^2.4, slog-scope ^4, log 0.4.11+ with the std feature), Rust 2018 edition, and an MSRV pinned to 1.38. An optional kv_unstable Cargo feature pulls in log/kv_unstable_std and slog/dynamic-keys to bridge log’s unstable structured key-value API into slog’s typed Serializer, implemented in a separate kv.rs module that’s only compiled when the feature is enabled. Dev-dependencies (slog-term, slog-async, fragile) are only used for doctest examples and the integration test; there’s no build script, proc-macro, or async runtime dependency.

Code Quality Test coverage is thin but present: tests/slog2log.rs exercises the slog→log direction with a hand-rolled log::Log implementation that asserts each forwarded record’s level, target, module, file, and args match expectations, while a second test (tests/log2slog.rs.disabled) is explicitly disabled, and the kv_unstable code path is marked #[ignore = "TODO"] in the existing test — meaning the newer structured-kv feature ships without regression coverage. The crate enables #![warn(missing_docs)] and every public item carries a doc comment, several with full runnable doctest examples. Naming and error handling stay simple and consistent (functions return log::SetLoggerError unchanged), though the README’s CI badge still points at a dead Travis CI build despite the project having since moved to GitHub Actions.

API Design The public surface is deliberately tiny: init() / init_with_level() for the common case of registering slog-stdlog as the global log backend in one call, and the StdLog drain type for the reverse direction, both demonstrated with complete, copy-pasteable doctest examples in lib.rs showing the required slog_scope::set_global_logger + slog_stdlog::init() pairing. There’s no configuration struct, builder, or trait to implement — consumers plug it directly into slog::Drain or log::set_boxed_logger — which keeps onboarding to a couple of lines, at the cost of no runtime control over formatting (that’s delegated entirely to whichever backend is installed downstream).

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search