info.remote_addr() – method not found in warp::log::Info

# `info.remote_addr()` - Method Not Found in warp::log::Info: A Production Postmortem

## Summary
A compilation error occurred when using `info.remote_addr()` within `warp::log::custom`. The method `remote_addr` is absent in `warp::log::Info`, causing the Rust compiler to reject the code. The issue stems from API differences between Warp's logging middleware and remote address extraction.

## Root Cause
* **API Changes:** The `remote_addr()` method was likely present in older Warp versions but removed or relocated in newer releases.
* **Logger Scope Limitation:** `warp::log::Info` provides request metadata (like method, path, status) but **doesn't include client IP** by default.
* **Context Separation:** Remote IP extraction requires a separate filter (`warp::addr::remote()`) due to its dependency on connection-level data unavailable in the logger's view.

## Why This Happens in Real Systems
* Dependency version drift between documentation/code examples and actual library versions.
* Confusion between middleware that **logs data** vs. middleware that **extracts data**.
* Insufficient compiler feedback on how to migrate deprecated/removed APIs.
* Reconciliation of distinct Warp concepts:
    - `log::custom`: Operates on request/response metadata.
    - `addr::remote`: Requires low-level transport info (e.g., TCP socket addresses).

## Real-World Impact
* **Failed Deployments:** Compilation breaks block CI/CD pipelines.
* **Delayed Features:** Developers waste time debugging instead of shipping features.
* **Incomplete Logging:** Missing client IPs hinder troubleshooting (e.g., blocking attackers, geo-routing).
* **Workaround Complexity:** Engineers rebuild logging middleware manually.

## Example or Code

### Broken Implementation (Original)
```rust
warp::log::custom(|info| {
    eprintln!(
        "... from {} ...",
        info.remote_addr().unwrap() // Compiler error: no `remote_addr`
    );
});

Fixed Implementation

let log = {
    let log = warp::log::custom(move |info| {
        eprintln!(
            "{} {} {} {:?}",
            info.method(),
            info.path(),
            info.status(),
            info.elapsed()
        );
    });

    // Combine with remote IP logging
    warp::log::custom(move |info| {
        if let Some(addr) = info.remote_addr() {
            println!("Request from IP: {}", addr);
        }
    }).or(log) // Chain logger middlewares
};

Alternative Approach Using Explicit Extraction

let remote_log = warp::log::custom(|info| {
    let ip = info
        .remote_addr()
        .map(|addr| addr.to_string())
        .unwrap_or_else(|| "unknown".into());
    eprintln!("{} requested {}", ip, info.path());
});

let routes = routes
    .with(remote_log) // Attach dedicated IP logger
    .with(warp::log::custom(/* base logger */));

How Senior Engineers Fix It

  • Check Documentation: Verify available methods in warp::log::Info struct.
  • Audit Dependencies: Cross-reference example code with installed Warp version.
  • Decouple Concerns: Merge logger and remote IP extraction using:
    • Composed middleware layers (filter::and/or)
    • Custom closures capturing explicit warp::addr::remote() data
  • Use Option Handling:
    • Replace .unwrap() with explicit Option checks for remote_addr().
  • Design Hybrid Loggers:
    • Capture IPs independently and inject into log formatting.
  • Update Examples: Replace deprecated calls with current equivalents.

Why Juniors Miss It

  • Reliance on Outdated Tutorials: Book examples may target older Warp versions.
  • Compiler Message Limits: Error suggests non-existent API without providing alternatives.
  • Conceptual Overload: Unfamiliarity with Warp’s middleware composition model.
  • API Surface Confusion: Expecting all metadata to exist in Info struct.
  • Debugging Bias: Focusing on syntax without analyzing struct definitions.