All Integrations
LanguagesCargo crate

Actix Web Integration

Instrument Rust Actix Web applications with one Cargo crate. Middleware, guard, and handler-level spans with Tokio runtime metrics — zero unsafe code required.

Setup

How It Works

01

Add the Cargo Crate

Add tigerops = "0.1" to your Cargo.toml [dependencies]. The crate bundles opentelemetry-actix-web bindings with a TigerOps OTLP exporter and a tokio-metrics collector for runtime task and thread pool visibility.

02

Wrap Your App with Middleware

Call .wrap(tigerops::actix::TigerOpsMiddleware::new()) on your App builder. The middleware implements actix_web::dev::Transform and creates root spans for every incoming request with zero unsafe code.

03

Set Environment Variables

Set TIGEROPS_API_KEY, TIGEROPS_SERVICE_NAME, and TIGEROPS_ENVIRONMENT before starting your Actix system. The crate reads these at initialization using std::env. The dotenvy crate is supported for .env file loading.

04

Traces, Guards & Tokio Metrics

Within seconds TigerOps receives Actix handler spans, guard evaluation results, extractor timing, Tokio task poll counts, and thread pool utilization from your Rust Actix Web application.

Capabilities

What You Get Out of the Box

Actix Middleware Spans

TigerOpsMiddleware implements the actix-web ServiceTransform trait and creates root spans for every HTTP request with route pattern, HTTP method, status code, peer address, and response time. Nested scopes are resolved to full path patterns.

Guard-Level Tracing

Custom actix-web Guard implementations can be wrapped with tigerops::guard::traced(guard) to measure guard evaluation time. Guard name, match result, and evaluation duration are recorded as span attributes on the request span.

Handler & Extractor Timing

Each route handler and its parameter extractors (Json<T>, Path<T>, Query<T>, Data<T>) have their deserialization and validation time measured. Slow extractors are identified without requiring any changes to handler signatures.

Tokio Runtime Metrics

tokio-metrics integration reports worker thread poll count, task schedule delay, task poll duration, overflow queue depth, and steal count per worker thread. These are emitted as OTLP metrics every 30 seconds.

SQLx & Diesel Query Spans

SQL queries issued via sqlx or diesel from handler tasks are automatically traced as child spans. Normalized query text, database URL host, execution time, and affected rows are recorded. Prepared statement cache hits are tracked.

Manual Span API via tracing Crate

TigerOps integrates with the tracing crate. Use #[tracing::instrument] on async handler functions for automatic span creation with typed field capture. The OpenTelemetry tracing bridge connects tracing spans to TigerOps automatically.

Configuration

Install & Initialize

One Cargo crate. One middleware wrap. Full Actix Web observability.

Cargo.toml + main.rs
# Cargo.toml
[dependencies]
actix-web = "4"
tigerops  = { version = "0.1", features = ["actix-web", "sqlx"] }
tokio     = { version = "1", features = ["full"] }
tracing   = "0.1"

# Set environment variables
# export TIGEROPS_API_KEY="your-api-key"
# export TIGEROPS_SERVICE_NAME="my-actix-app"
# export TIGEROPS_ENVIRONMENT="production"

// main.rs
use actix_web::{web, App, HttpServer, HttpResponse};
use tigerops::actix::TigerOpsMiddleware;

#[tracing::instrument(fields(order.items = body.items.len()))]
async fn create_order(body: web::Json<OrderRequest>) -> HttpResponse {
    let order = process_order(body.into_inner()).await;
    HttpResponse::Created().json(order)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    // TigerOps reads TIGEROPS_API_KEY, SERVICE_NAME, ENVIRONMENT
    tigerops::init().expect("TigerOps init failed");

    HttpServer::new(|| {
        App::new()
            .wrap(TigerOpsMiddleware::new())  // <-- single wrap
            .route("/orders", web::post().to(create_order))
            .route("/health", web::get().to(|| async {
                HttpResponse::Ok().body("ok")
            }))
    })
    .bind("0.0.0.0:3000")?
    .run()
    .await
}
FAQ

Common Questions

Which Actix Web and Rust editions are supported?

Actix Web 4.x is fully supported with Rust edition 2021 on Rust stable 1.75+. The crate compiles on stable Rust without any nightly features. Actix Web 3.x requires the tigerops-actix3 compatibility shim.

How does TigerOps handle Actix actors?

The tigerops-actix-actors feature flag enables actor message tracing. Wrap your actor handler impl with #[tigerops::actor_handler] to create a span for each message handled. Actor mailbox depth is tracked as a gauge metric.

Does TigerOps work with Actix Web running behind an AWS ALB or nginx?

Yes. Configure the trusted_proxies option in TigerOpsConfig to list your proxy CIDR ranges. TigerOps reads X-Forwarded-For and X-Forwarded-Proto from trusted proxies and attaches the real client IP and scheme to request spans.

Can I use TigerOps with Actix Web hosted on AWS Lambda via the lambda-web crate?

Yes. The crate auto-detects the AWS Lambda environment via the AWS_LAMBDA_FUNCTION_NAME environment variable and switches to a synchronous OTLP export strategy that flushes before the Lambda invocation completes.

How do I instrument background tasks spawned with tokio::spawn inside a handler?

Use tigerops::spawn(async move { ... }) instead of tokio::spawn to propagate the current trace context into the spawned task. The spawned task creates a linked span rather than a child span to correctly model the async fork.

Get Started

Full Actix Web Observability in One Cargo Crate

Handler traces, guard evaluation, Tokio metrics, and SQLx query spans — no code changes required.