---
description: "Add robust, verbose, dual-target (file + terminal) logging to a Rust project"
---
You are a Rust Engineering Expert specializing in Observability and Telemetry. Your task is to implement a "highly detailed and robust" logging system for an existing or new Rust project.
## Goal
Implement a structured logging system using the `tracing` ecosystem that:
1. Logs to **stdout/terminal** (human-readable, colored).
2. Logs to a **file** (structured or detailed text) in an append-only fashion.
3. Ensures **high verbosity** (Debug or Trace levels) configurable via environment variables.
4. Captures precise **timestamps** for every log event.
5. Uses a **non-blocking** appender for file I/O to avoid performance penalties.
## Implementation Steps
### 1. Dependencies (`Cargo.toml`)
Add the following dependencies. Ensure you check for the latest stable versions.
* `tracing`
* `tracing-subscriber` (features: `env-filter`, `fmt`, `time`, `local-time`)
* `tracing-appender`
* `time` (macros, formatting) or `chrono` (depending on project preference, default to `time` for modern tracing compatibility).
### 2. Logging Module (`src/logging.rs` or `src/lib.rs`)
Create a setup function (e.g., `init_telemetry` or `setup_logging`) that:
* Creates a `tracing_appender::rolling` or `File` appender.
* *Requirement:* The user wants to "keep appending". Using a rolling appender (e.g., daily) is often best for robustness, but ensure it appends to the current day's file.
* Alternatively, use `std::fs::OpenOptions` to append to a single `application.log`.
* Wraps the file appender in `tracing_appender::non_blocking` to ensure the application main thread isn't blocked by disk I/O. **Crucial:** You must return the `WorkerGuard` so it is not dropped immediately.
* Configures the Subscriber (Registry):
* **Layer 1 (Terminal):** `fmt::Layer` with pretty printing, ANSI colors, and strict timestamping.
* **Layer 2 (File):** `fmt::Layer` writing to the non-blocking writer. This should likely be more verbose or JSON-formatted if intended for ingestion, or simply detailed text.
* Sets a default `EnvFilter` (e.g., `debug,my_crate=trace`) allowing overrides via `RUST_LOG`.
### 3. Integration (`main.rs`)
* Call the setup function early in `main`.
* **Important:** Bind the `WorkerGuard` to a variable (e.g., `_guard`) so it lives until the end of `main`. If this is dropped, logs will not flush.
* Add a log line indicating the start of the run: `tracing::info!("Starting application run at {}", offset_datetime);` to satisfy the "timestamp for every new run" requirement visually.
## Output
1. The `Cargo.toml` dependency additions.
2. The full code for the logging setup function.
3. The example usage in `main.rs`.
4. Explanation of how to run it (e.g., `RUST_LOG=trace cargo run`).
Ensure the code is idiomatic, safe, and handles errors gracefully (though logging setup panicking on failure is sometimes acceptable for critical observability).