Crate axum_prometheus
source ·Expand description
A middleware to collect HTTP metrics for Axum applications.
axum-prometheus
relies on metrics.rs
and its ecosystem to collect and export metrics - for instance for Prometheus, metrics_exporter_prometheus
is used as a backend to interact with Prometheus.
§Metrics
By default three HTTP metrics are tracked
axum_http_requests_total
(labels: endpoint, method, status): the total number of HTTP requests handled (counter)axum_http_requests_duration_seconds
(labels: endpoint, method, status): the request duration for all HTTP requests handled (histogram)axum_http_requests_pending
(labels: endpoint, method): the number of currently in-flight requests (gauge)
This crate also allows to track response body sizes as a histogram — see PrometheusMetricLayerBuilder::enable_response_body_size
.
§Renaming Metrics
These metrics can be renamed by specifying environmental variables at compile time:
AXUM_HTTP_REQUESTS_TOTAL
AXUM_HTTP_REQUESTS_DURATION_SECONDS
AXUM_HTTP_REQUESTS_PENDING
AXUM_HTTP_RESPONSE_BODY_SIZE
(if body size tracking is enabled)
These environmental variables can be set in your .cargo/config.toml
since Cargo 1.56:
[env]
AXUM_HTTP_REQUESTS_TOTAL = "my_app_requests_total"
AXUM_HTTP_REQUESTS_DURATION_SECONDS = "my_app_requests_duration_seconds"
AXUM_HTTP_REQUESTS_PENDING = "my_app_requests_pending"
AXUM_HTTP_RESPONSE_BODY_SIZE = "my_app_response_body_size"
..or optionally use PrometheusMetricLayerBuilder::with_prefix
function.
§Usage
For more elaborate use-cases, see the builder-example that leverages PrometheusMetricLayerBuilder
.
Add axum-prometheus
to your Cargo.toml
.
[dependencies]
axum-prometheus = "0.6.1"
Then you instantiate the prometheus middleware:
use std::{net::SocketAddr, time::Duration};
use axum::{routing::get, Router};
use axum_prometheus::PrometheusMetricLayer;
#[tokio::main]
async fn main() {
let (prometheus_layer, metric_handle) = PrometheusMetricLayer::pair();
let app = Router::new()
.route("/fast", get(|| async {}))
.route(
"/slow",
get(|| async {
tokio::time::sleep(Duration::from_secs(1)).await;
}),
)
.route("/metrics", get(|| async move { metric_handle.render() }))
.layer(prometheus_layer);
let listener = tokio::net::TcpListener::bind(SocketAddr::from(([127, 0, 0, 1], 3000)))
.await
.unwrap();
axum::serve(listener, app).await.unwrap()
}
Note that the /metrics
endpoint is not automatically exposed, so you need to add that as a route manually.
Calling the /metrics
endpoint will expose your metrics:
axum_http_requests_total{method="GET",endpoint="/metrics",status="200"} 5
axum_http_requests_pending{method="GET",endpoint="/metrics"} 1
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="0.005"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="0.01"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="0.025"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="0.05"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="0.1"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="0.25"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="0.5"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="1"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="2.5"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="5"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="10"} 4
axum_http_requests_duration_seconds_bucket{method="GET",status="200",endpoint="/metrics",le="+Inf"} 4
axum_http_requests_duration_seconds_sum{method="GET",status="200",endpoint="/metrics"} 0.001997171
axum_http_requests_duration_seconds_count{method="GET",status="200",endpoint="/metrics"} 4
§Using a different exporter than Prometheus
This crate may be used with other exporters than Prometheus. First, disable the default features:
axum-prometheus = { version = "0.6.1", default-features = false }
Then implement the MakeDefaultHandle
for the provider you’d like to use. For StatsD
:
use metrics_exporter_statsd::StatsdBuilder;
use axum_prometheus::{MakeDefaultHandle, GenericMetricLayer};
// A marker struct for the custom StatsD exporter.
struct Recorder;
// In order to use this with `axum_prometheus`, we must implement `MakeDefaultHandle`.
impl MakeDefaultHandle for Recorder {
type Out = ();
fn make_default_handle() -> Self::Out {
// The regular setup for StatsD..
let recorder = StatsdBuilder::from("127.0.0.1", 8125)
.with_queue_size(5000)
.with_buffer_size(1024)
.build(Some("prefix"))
.expect("Could not create StatsdRecorder");
metrics::set_boxed_recorder(Box::new(recorder)).unwrap();
// We don't need to return anything meaningful from here (unlike PrometheusHandle)
// Let's just return an empty tuple.
()
}
}
fn main() {
// ...
// Use `GenericMetricLayer` instead of `PrometheusMetricLayer`.
let (metric_layer, _handle) = GenericMetricLayer::<'_, _, Recorder>::pair();
// ...
}
This crate is similar to (and takes inspiration from) actix-web-prom
and rocket_prometheus
,
and also builds on top of davidpdrsn’s earlier work with LifeCycleHooks in tower-http
.
Re-exports§
pub use metrics;
pub use metrics_exporter_prometheus;
Modules§
- Request lifecycle hooks that can be used to further customize how and what callbacks to run on events.
- Utilities for getting metric names at runtime, and other helpers.
Structs§
- A marker struct that implements
lifecycle::OnBodyChunk
, so it can be used to track response body sizes. - The tower middleware layer for recording http metrics with different exporters.
- The default handle for the Prometheus exporter.
- A builder for
GenericMetricLayer
that enables further customizations. - Struct used for storing and calculating information about the current request.
- A marker struct that implements the
lifecycle::Callbacks
trait.
Enums§
- Determines how endpoints are reported.
Constants§
- Identifies the histogram/summary used for request latency. Defaults to
axum_http_requests_duration_seconds
, but can be changed by setting theAXUM_HTTP_REQUESTS_DURATION_SECONDS
env at compile time. - Identifies the gauge used for the requests pending metric. Defaults to
axum_http_requests_pending
, but can be changed by setting theAXUM_HTTP_REQUESTS_PENDING
env at compile time. - Identifies the counter used for requests total. Defaults to
axum_http_requests_total
, but can be changed by setting theAXUM_HTTP_REQUESTS_TOTAL
env at compile time. - Identifies the histogram/summary used for response body size. Defaults to
axum_http_response_body_size
, but can be changed by setting theAXUM_HTTP_RESPONSE_BODY_SIZE
env at compile time.
Traits§
- The trait that allows to use a metrics exporter in
GenericMetricLayer
.
Type Aliases§
- The tower middleware layer for recording http metrics with Prometheus.
- A builder for
crate::PrometheusMetricLayer
that enables further customizations.