tiny-tracing
A lightweight, builder-style logging library for Rust that wraps tracing and
tracing-subscriber. Designed for small to medium projects that want structured or
plain-text output with zero fuss.
[!NOTE] AI coding assistants are used in this project mainly for best-practice and design guidance (through the agent skills listed below), to keep the library as simple and productive as possible, and above all to document its functions.
Quickstart
Add the crate to your project:
cargo add tiny-tracing
Minimal setup — text output at INFO level, nothing else needed:
use Logger;
Configuration
The builder API exposes every knob through chainable methods:
use ;
| Method | Default | Description |
|---|---|---|
with_level(Level::DEBUG) |
Level::INFO |
Global log level (tracing::Level); with_env_filter refines it per-target |
with_format(LogFormat::Json) |
LogFormat::Text |
Output format |
with_env_filter("info,my_crate=debug") |
none | Per-target filter via EnvFilter, layered on the level |
with_env_filter_from_env() |
none | Reads the filter from RUST_LOG; if it is unset, only the level applies |
with_file(true) |
false |
Show source file path in log lines |
with_target(false) |
true |
Show module path in log lines |
with_timestamp(false) |
true |
Prefix each line with a UTC RFC 3339 timestamp |
with_output(Output::Both("app.log".into())) |
Output::Stdout |
Write to stdout, stderr, a file, or both stdout and a file |
colored(false) |
auto | Force ANSI colours on or off; by default they are on only when the output stream (stdout or stderr) is a terminal |
Output destinations
with_output takes an Output: Stdout (default), Stderr, File(path), or Both(path) (stdout plus a file). Use Stderr in
command-line tools so stdout stays free for program output.
File output is opened in append mode (created if missing) with synchronised,
blocking writes — no background thread, no guard to keep alive.
Colours
By default ANSI colours are used only when the stream being written to is a terminal, so piped output,
Docker and CI logs stay free of escape codes. Call colored(true) or colored(false)
to override that. File output is never coloured, whatever you choose. The NO_COLOR
environment variable is not read; use colored(false) if you want to honour it
yourself.
Timestamps
By default every log line carries an RFC 3339 timestamp in UTC (for example
2026-10-01T12:00:00.123456Z), in both text and JSON output. The sub-second
fraction has a variable length because trailing zeros are trimmed. Local time is not
supported, so lines from different hosts are easy to correlate.
Call with_timestamp(false) to leave the timestamp out, for example when journald or
your container runtime already adds its own. In JSON output the timestamp field is
then omitted too.
Environment filter
with_env_filter("info,my_crate=debug") takes the directives as a string.
with_env_filter_from_env() reads them from RUST_LOG instead. If RUST_LOG is unset
only the level applies, and an invalid value makes init() return
LoggerError::InvalidEnvFilter. A global directive in the filter (such as
RUST_LOG=warn) takes precedence over with_level.
Need to load config from a string (env var, TOML)? LogFormat implements FromStr,
and tracing::Level does too:
use ;
let format: LogFormat = "json".parse?;
let level: Level = "debug".parse?;
# Ok::
Examples
Runnable examples live under examples/:
Limitations
tiny-tracing is deliberately a thin wrapper, so some things are left out on purpose:
- File writes are blocking. Each log line is written synchronously under a mutex,
with no background thread. That is fine for small and medium workloads, but heavy
logging from many threads or from async tasks can contend on the lock. If you need
non-blocking writes, use
tracing-appenderwithtracing-subscriberdirectly. - No file rotation. The log file is only ever appended to and grows without bound.
Rotate it externally (for example with
logrotate) or usetracing-appender's rolling files. - In containers, log to stdout. In Docker, Kubernetes or systemd, keep the default
Output::Stdoutand let the platform collect and rotate the logs, rather than writing files inside the container.LogFormat::Jsonis usually the best fit for log aggregators, and colours switch off by themselves because stdout is not a terminal. UseOutput::Stderrinstead for command-line tools whose stdout carries data.
Planned improvements are tracked in roadmap.md.
Safety
The library calls tracing_subscriber::try_init() internally — calling init() more
than once returns a LoggerError::TryInitError instead of panicking. No unsafe code
anywhere in the crate.
To report a vulnerability, see the security policy.
License
tiny-tracing is distributed under the terms of the MIT license.
Development
Releases are automated via cocogitto (Conventional Commits). See the release skill for the full workflow.
Minimum supported Rust version (MSRV)
rust-version in Cargo.toml is the oldest Rust the crate promises to build with. It is
independent of rust-toolchain.toml, which only pins the toolchain used for development.
CI checks it with the msrv job. After bumping dependencies or adding code that needs a
newer compiler, measure the real minimum with
cargo-msrv:
Then update rust-version in Cargo.toml, the MSRV badge at the top of this file and the
msrv job in .github/workflows/ci.yml to the same version.
Agent skills
AI coding agents working on this repo use these third-party skills (installed under
.claude/skills/, pinned in skills-lock.json):
The release skill is specific to this repo and not installed from anywhere.