Introduction to Logging in Rust
Logging is the process of recording information about a program's operation. For beginner Rust developers, logging might seem complex, but it is actually one of the most powerful tools for debugging and monitoring. In this article, we will cover the best practices for logging in Rust that will help you write more reliable and maintainable applications.
Why is logging so important? Imagine your application unexpectedly crashes in production. Without logs, you are left completely in the dark — you have to guess what went wrong. With properly configured logging, you can quickly find and fix the error. In Rust, the logging ecosystem is built on powerful and flexible crates, which we will explore today.
1. Logging Basics: The log Crate
In Rust, the de facto standard for logging is the log crate. It provides an abstract interface that is independent of any specific implementation. This means you can write code using macros from log and then switch between different backends (e.g., env_logger, log4rs, or slog) without changing the core code.
Installation and Setup
Add the dependency to your Cargo.toml:
[dependencies]log = "0.4"env_logger = "0.10"Now you can use the logging macros in your code. Here is a simple example:
use log::{info, warn, error};
fn main() { // Initialize the logger env_logger::init();
let user = "Alexey"; let age = 25;
info!("Application started"); warn!("User {} is {} years old, verify the data", user, age); error!("Failed to connect to the database");
println!("Program finished");}Important: without calling env_logger::init(), the log macros will not output anything. Initialization should happen once at the very beginning of the program.
Logging Levels
The log crate supports five logging levels (from most to least important):
error!— critical errors requiring immediate attention. Use for situations where the program cannot continue.warn!— warnings. Something went wrong, but the program can continue (e.g., deprecated API or unexpected value).info!— general information about the program's execution. Useful for tracking key events (startup, shutdown, important transitions).debug!— debugging information. Used during development for detailed analysis.trace!— the most detailed level. Records every step of execution. Use with caution — it can heavily clutter the output.
Filtering by level happens automatically. By default, env_logger outputs all messages with the error, warn, and info levels. You can easily change this using the RUST_LOG environment variable:
# Show only errorsRUST_LOG=error cargo run
# Show everything, including traceRUST_LOG=trace cargo run
# Show only for a specific moduleRUST_LOG=my_module=debug cargo run2. Practical Logging: Structured Logs
Simple string logging is fine, but for production systems, it is better to use structured logs. Instead of writing "User Alexey logged in", you can record a JSON object with fields like event, user, timestamp. This simplifies log analysis with tools like Elasticsearch or Grafana.