rustlift 2.0.1

A typestate-driven deployment agent for Azure Web Apps
Documentation
---
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).