Diagnostics
| eprintln! to stderr | |
| dbg! snapshots | |
| assert and debug_assertions | |
| Log levels by hand |
eprintln! to stderr
Normal output goes to stdout, but errors belong on stderr so they survive pipelines. The eprintln macro formats like println but writes to the error stream:
use std::env;
fn main() {
if env::args().len() < 2 {
eprintln!("usage: prog <input>");
std::process::exit(1);
}
}
Redirect stdout to a file and the error still reaches the terminal. That split is why tools print usage with eprintln and not println.
dbg! snapshots
The dbg macro prints a value plus its file and line, then hands the value back. Wrap any expression to take a quick snapshot while debugging:
fn main() {
let total = dbg!(40 + 2);
println!("total: {}", total);
}
assert and debug_assertions
Assertions state facts your code depends on. The assert macro panics with a message when the condition is false, and debug_assert only checks in debug builds:
fn main() {
let n: u32 = "42".parse().unwrap();
assert!(n > 0);
assert_eq!(n, 42);
debug_assert!(n < 100);
}
Use assert for promises that must hold everywhere, and debug_assert for expensive checks you only want during development.
Log levels by hand
The standard library ships no logger, so small tools roll their own levels with one helper. Prefix each line and send it to stderr:
fn log(level: &str, msg: &str) {
eprintln!("[{}] {}", level, msg);
}
fn main() {
log("INFO", "server started");
log("ERROR", "disk is full");
}
INFO lines narrate progress while ERROR lines flag trouble. When this helper outgrows you, that is the moment to learn a logging crate.
Next: Time
Article author: Arthur Isaev