Edge Request Timing and Logging

When your code runs across 100+ edge locations worldwide, understanding what each worker is doing becomes critical for debugging, optimization, and reliability. FastEdge provides logging and timing capabilities that give you visibility into every request processed at the edge.

This post covers Edge Request Timing and Logging — a pattern for adding observability to your edge workers.

Why Edge Observability Matters

Log request processing times and other metrics from your FastEdge workers for observability and debugging.

Without observability at the edge, you're flying blind. A slow response could be caused by a cold start, a network issue at a specific PoP, or a bug in your edge logic — and you'd have no way to tell which. Adding logging and timing to your workers turns them from black boxes into transparent, debuggable components.

Implementation

Here is how you add request timing and logging to your FastEdge worker:

use fastedge::{
    body::Body,
    http::{Request, Response, StatusCode, Error},
    logging,
};
use std::time::Instant;

#[fastedge::http]
fn main(req: Request<Body>) -> Result<Response<Body>, Error> {
    let start = Instant::now();

    // Log incoming request details
    logging::info!("Request: {} {}",
        req.method(),
        req.uri().path()
    );

    // Your request processing logic
    let result = process_request(req);

    // Log timing information
    let elapsed = start.elapsed();
    logging::info!("Processed in {:?} (status: {})",
        elapsed,
        result.status()
    );

    result
}

fn process_request(req: Request<Body>) -> Result<Response<Body>, Error> {
    let path = req.uri().path();
    match path {
        "/fast" => {
            // Simulate fast processing
            Response::builder()
                .status(StatusCode::OK)
                .body(Body::from("Fast response"))
        }
        "/slow" => {
            // Simulate slow upstream
            std::thread::sleep(std::time::Duration::from_millis(50));
            Response::builder()
                .status(StatusCode::OK)
                .body(Body::from("Slow response"))
        }
        _ => Response::builder()
            .status(StatusCode::NOT_FOUND)
            .body(Body::from("Not found"))
    }
}

What You Can Track

Log Levels

The FastEdge SDK supports standard log levels: trace, debug, info, warn, and error. Use them appropriately to avoid noise while retaining the ability to debug production issues:

logging::trace!("Detailed step-by-step debugging");
logging::debug!("KV lookup took: {:?}, result: {:?}", elapsed, value);
logging::info!("Request processed successfully");
logging::warn!("Slow upstream response: {:?}", elapsed);
logging::error!("Failed to connect to origin: {}", error);
Tip: Combine edge logging with structured logging at your origin for end-to-end request tracing. Include a unique request ID in edge logs that gets passed to upstream services via headers.