Expand description

OpenTelemetry integration for Actix Web.

This crate allows you to easily instrument client and server requests.

  • Server requests can be traced by using the RequestTracing middleware.

The awc feature allows you to instrument client requests made by the awc crate.

The metrics feature allows you to expose request metrics to Prometheus.

Client Request Examples:

Note: this requires the awc feature to be enabled.

use awc::{Client, error::SendRequestError};
use actix_web_opentelemetry::ClientExt;

async fn execute_request(client: &Client) -> Result<(), SendRequestError> {
    let res = client
        .get("http://localhost:8080")
        // Add `trace_request` before `send` to any awc request to add instrumentation
        .trace_request()
        .send()
        .await?;

    println!("Response: {:?}", res);
    Ok(())
}

Server middleware examples:

Tracing and metrics middleware can be used together or independently.

Tracing server example:

use actix_web::{web, App, HttpServer};
use actix_web_opentelemetry::RequestTracing;

async fn index() -> &'static str {
    "Hello world!"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // Install an OpenTelemetry trace pipeline.
    // Swap for https://docs.rs/opentelemetry-jaeger or other compatible
    // exporter to send trace information to your collector.
    opentelemetry::sdk::export::trace::stdout::new_pipeline().install_simple();

    HttpServer::new(|| {
        App::new()
            .wrap(RequestTracing::new())
            .service(web::resource("/").to(index))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

Request metrics middleware (requires the metrics feature):

use actix_web::{dev, http, web, App, HttpRequest, HttpServer};
use actix_web_opentelemetry::{PrometheusMetricsHandler, RequestMetricsBuilder, RequestTracing};
use opentelemetry::{
    global,
    sdk::{
        export::metrics::aggregation,
        metrics::{controllers, processors, selectors},
        propagation::TraceContextPropagator,
    },
};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let controller = controllers::basic(
        processors::factory(
            selectors::simple::histogram([1.0, 2.0, 5.0, 10.0, 20.0, 50.0]),
            aggregation::cumulative_temporality_selector(),
        )
        .with_memory(true),
    )
    .build();
    let exporter = opentelemetry_prometheus::exporter(controller).init();
    let meter = global::meter("actix_web");

    // Request metrics middleware
    let request_metrics = RequestMetricsBuilder::new().build(meter);

    // Run actix server, metrics are now available at http://localhost:8080/metrics
    HttpServer::new(move || {
        App::new()
            .wrap(RequestTracing::new())
            .wrap(request_metrics.clone())
            .route("/metrics", web::get().to(PrometheusMetricsHandler::new(exporter.clone())))
        })
        .bind("localhost:8080")?
        .run()
        .await
}

Exporter configuration

actix-web uses tokio as the underlying executor, so exporters should be configured to be non-blocking:

[dependencies]
# if exporting to jaeger, use the `tokio` feature.
opentelemetry-jaeger = { version = "..", features = ["rt-tokio-current-thread"] }

# if exporting to zipkin, use the `tokio` based `reqwest-client` feature.
opentelemetry-zipkin = { version = "..", features = ["reqwest-client"], default-features = false }

# ... ensure the same same for any other exporters

Structs

A wrapper for the actix-web awc::ClientRequest.
PrometheusMetricsHandlermetrics-prometheus and metrics
Prometheus request metrics service
Request metrics tracking
Request metrics middleware
Request tracing middleware.
Request tracing middleware

Traits

OpenTelemetry extensions for actix-web’s awc::Client.
Interface for formatting routes from paths.