Crate actix_web_opentelemetry
source ·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.
- Client requests can be traced by using the
ClientExt::trace_request
method.
The metrics
feature allows you to expose request metrics to Prometheus.
- Metrics can be tracked using the
RequestMetrics
middleware.
§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;
use opentelemetry::global;
use opentelemetry_sdk::trace::TracerProvider;
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.
let exporter = opentelemetry_stdout::SpanExporter::default();
// Configure your tracer provider with your exporter(s)
let provider = TracerProvider::builder()
.with_simple_exporter(exporter)
.build();
global::set_tracer_provider(provider);
// add the request tracing middleware to create spans for each request
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, RequestMetrics, RequestTracing};
use opentelemetry::global;
use opentelemetry_sdk::metrics::SdkMeterProvider;
#[actix_web::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configure prometheus or your preferred metrics service
let registry = prometheus::Registry::new();
let exporter = opentelemetry_prometheus::exporter()
.with_registry(registry.clone())
.build()?;
// set up your meter provider with your exporter(s)
let provider = SdkMeterProvider::builder()
.with_reader(exporter)
.build();
global::set_meter_provider(provider);
// Run actix server, metrics are now available at http://localhost:8080/metrics
HttpServer::new(move || {
App::new()
.wrap(RequestTracing::new())
.wrap(RequestMetrics::default())
.route("/metrics", web::get().to(PrometheusMetricsHandler::new(registry.clone())))
})
.bind("localhost:8080")?
.run()
.await;
Ok(())
}
§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.
- PrometheusMetricsHandler
metrics-prometheus
andmetrics
Prometheus request metrics service - RequestMetrics
metrics
Request metrics tracking - RequestMetricsBuilder
metrics
Builder for RequestMetrics - RequestMetricsMiddleware
metrics
Request metrics middleware - Request tracing middleware.
- Request tracing middleware
Traits§
- ClientExt
awc
OpenTelemetry extensions for actix-web’s awc::Client. - Interface for formatting routes from paths.