Logging in Rust: Overview of the Best Libraries and Solutions

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Logging for Rust: Best Libraries and Tools



Logging is an essential part of developing any serious application. In the Rust ecosystem, there are several mature solutions that allow flexible management of message output, setting severity levels, and formats. In this article, we will look at the most popular libraries for logging in Rust, their features, and provide usage examples.



1. The Base log Trait



The log library (crate log) is the foundation for all logging systems in Rust. It provides the abstract Log trait and macros (info!, warn!, error!, debug!, trace!). By itself, it does not output data — an implementation (backend) is required for that.



// Cargo.toml// [dependencies]// log = "0.4"

use log::{info, warn, error};

fn main() { info!("Application started"); warn!("Low memory: {} MB", 128); error!("Database connection error");}


Logging levels in ascending order of severity: trace, debug, info, warn, error. By default, only messages at the info level and above are displayed.



2. env_logger — Simple and Popular Choice



env_logger is the most common implementation of the Log trait. It is configured via the RUST_LOG environment variable and outputs messages to the standard error stream (stderr).



// Cargo.toml// [dependencies]// log = "0.4"// env_logger = "0.10"

use log::info;

fn main() { env_logger::init(); info!("env_logger initialized");}

// Run: RUST_LOG=info cargo run


Features:

  • Minimal setup — just one line env_logger::init() is enough.
  • Module-level filtering: RUST_LOG=my_crate=debug,other_crate=info.
  • Supports colored output in the terminal.
  • Ideal for small utilities and prototypes.


3. log4rs — Configurable Analog of log4j/log4net



log4rs (crate log4rs) is a powerful framework inspired by Java log4j. It allows configuring logging via YAML/JSON/TOML files or programmatically.



// Cargo.toml// [dependencies]// log = "0.4"// log4rs = "1.2"

use log::info;

fn main() { // Programmatic configuration log4rs::init_file("log4rs.yaml", Default::default()).unwrap(); info!("log4rs configured via file");}

// log4rs.yaml// refresh_rate: 30 seconds// appenders:// stdout:// kind: console// encoder:// pattern: "{d(%Y-%m-%d %H:%M:%S)} {l} - {m}{n}"// file:// kind: file// path: "app.log"// encoder:// pattern: "{d} {l} {t} - {m}{n}"// root:// level: info// appenders:// - stdout// - file


Features:

  • Support for multiple appenders (output to file, console, syslog, network).
  • Automatic log rotation by size or time.
  • Filtering by modules, levels, and custom filters.
  • Recommended for server applications and microservices.


4. tracing — Asynchronous and Structured Logging



tracing (crate tracing) is a modern alternative developed by the Tokio team. It supports structured events, spans for tracking execution time, and asynchronous contexts.



// Cargo.toml// [dependencies]// tracing = "0.1"// tracing-subscriber = "0.3"

use tracing::{info, span, Level};use tracing_subscriber::fmt;

fn main() { // Initialize subscriber fmt::init();

let span = span!(Lev

Recommendations