tracing-bunyan-formatter
Bunyan-formatted structured JSON logging layers for the Rust tracing ecosystem
Repository Health
Technical Analysis
tracing-bunyan-formatter provides two tracing Layer implementations that turn events and spans into structured, Bunyan-compatible JSON log records. It plugs into the tokio-rs/tracing Subscriber stack, making it easy to emit machine-parseable logs that downstream tools like the bunyan CLI can pretty-print and filter.
The crate pairs a JsonStorageLayer, which attaches contextual key-value data to spans for consumption by later layers, with a BunyanFormattingLayer that serializes events and span lifecycle into newline-delimited JSON. This gives Rust services production-grade structured logging with minimal boilerplate.
What You Get
- BunyanFormattingLayer, which serializes tracing events and span lifecycle into newline-delimited Bunyan JSON
- JsonStorageLayer, which captures contextual span fields for downstream layers to reuse
- Compatibility with the bunyan CLI for human-friendly log rendering and filtering
- Optional feature flags for hostname capture, arbitrary-precision numbers, and valuable support
Common Use Cases
- Emitting structured JSON logs from tokio-based async Rust web services
- Feeding logs into aggregation pipelines and dashboards that expect JSON records
- Propagating request-scoped context like request IDs across spans and their events
- Pretty-printing and filtering production logs locally with the bunyan CLI
Under The Hood
Architecture - The crate is split into two composable tracing_subscriber Layers. src/storage_layer.rs (~212 lines) implements JsonStorageLayer, which uses span extensions to build a JsonStorage map of contextual fields as spans are created, entered, and record new values. src/formatting_layer.rs (~396 lines) implements BunyanFormattingLayer, which reads that stored context and serializes each event plus span open/close into a Bunyan-shaped JSON object written to a configurable output. src/lib.rs is a thin module that re-exports the public types.
Tech Stack - Rust edition 2018 built on tracing, tracing-subscriber, tracing-core, and tracing-log, using serde and serde_json for output, time for timestamps, ahash for internal maps, and optional gethostname for the hostname field. Feature flags gate hostname capture (default), arbitrary-precision numbers, and valuable structured-value support.
Code Quality - The codebase is small, focused, and well-factored into storage versus formatting concerns. A tests directory exercises the JSON output using claims assertions and lazy_static fixtures, and an examples directory demonstrates usage including the valuable feature. The project is mature and stable though currently in low-maintenance mode.
API Design - Setup is idiomatic tracing: construct the two layers and register them on a Subscriber via with(). Because it follows the standard Layer composition pattern, developers already using tracing-subscriber need almost no new concepts, and the README documents the layer roles and Bunyan output clearly.