Skip to main content

Crate penna

Crate penna 

Source
Expand description

Structured JSON logging for tracing, one line per event.

A service that logs JSON lines to stdout and filters them by level needs a timestamp, an escaper and a comparison against a target prefix. The usual way to get that pulls in a regex engine, an ANSI colour library, a sharded slab and a thread-local crate, none of which a JSON line ever touches. penna has one dependency — tracing-core, which defines the traits — and writes the same lines.

penna::json().install();

tracing::info!(events = 5000, backup_key = "…", "telemetry events persisted");
{"timestamp":"2026-09-21T00:56:59.991167Z","level":"INFO","fields":{"message":"telemetry events persisted","events":5000,"backup_key":"…"},"target":"my_service"}

That shape is deliberate: it is what tracing-subscriber’s JSON formatter emits with its defaults, so a dashboard or log pipeline already parsing those lines keeps working.

§Filtering

Builder::filter takes the same directives as RUST_LOG, read by Builder::install when no filter is set:

info                            everything at info and above
warn,my_service=debug           debug for one module, warn elsewhere
my_service::spool=trace         one module, everything else off

A directive is a target prefix and a level. Matching is by path prefix on module boundaries — my_service matches my_service::spool but not my_service_other — and the longest matching prefix wins, so a specific directive overrides a general one whatever order they appear in. There is no regex, no field matching and no span filtering; if you need those, tracing-subscriber’s EnvFilter is the right tool.

§Spans

Open spans ride along on every event inside them: the innermost as span and the whole stack as spans, each with the fields it was created with. Nothing is printed when a span opens or closes — a span is context for the events inside it, not an event.

Structs§

Builder
A subscriber being configured.
Filter
A parsed set of directives. Build one with Filter::parse or Filter::from_env.
Penna
The subscriber. Build it with json.
Stderr
Writes to standard error, locked per line.
Stdout
Writes to standard output, locked per line.

Traits§

MakeWriter
Supplies a writer for each line.

Functions§

json
Starts building a subscriber that writes JSON lines to stdout.