mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-14 13:43:48 +01:00
Add metrics example (#671)
This commit is contained in:
parent
031e0fd472
commit
5698fb8be9
3 changed files with 113 additions and 1 deletions
9
.github/workflows/CI.yml
vendored
9
.github/workflows/CI.yml
vendored
|
@ -166,4 +166,11 @@ jobs:
|
|||
CC: clang
|
||||
with:
|
||||
command: check
|
||||
args: --all --all-targets --all-features --target armv5te-unknown-linux-musleabi
|
||||
args: >
|
||||
--all-targets
|
||||
--all-features
|
||||
-p axum
|
||||
-p axum-core
|
||||
-p axum-extra
|
||||
-p axum-debug
|
||||
--target armv5te-unknown-linux-musleabi
|
||||
|
|
14
examples/prometheus-metrics/Cargo.toml
Normal file
14
examples/prometheus-metrics/Cargo.toml
Normal file
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "example-prometheus-metrics"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
axum = { path = "../../axum" }
|
||||
axum-extra = { path = "../../axum-extra" }
|
||||
metrics = "0.17"
|
||||
metrics-exporter-prometheus = "0.7"
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
91
examples/prometheus-metrics/src/main.rs
Normal file
91
examples/prometheus-metrics/src/main.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
//! Someday tower-http will hopefully have a metrics middleware, until then you can track
|
||||
//! metrics like this.
|
||||
//!
|
||||
//! Run with
|
||||
//!
|
||||
//! ```not_rust
|
||||
//! cargo run -p example-prometheus-metrics
|
||||
//! ```
|
||||
|
||||
use axum::{extract::MatchedPath, http::Request, response::IntoResponse, routing::get, Router};
|
||||
use axum_extra::middleware::{self, Next};
|
||||
use metrics_exporter_prometheus::{Matcher, PrometheusBuilder, PrometheusHandle};
|
||||
use std::{
|
||||
future::ready,
|
||||
net::SocketAddr,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Set the RUST_LOG, if it hasn't been explicitly defined
|
||||
if std::env::var_os("RUST_LOG").is_none() {
|
||||
std::env::set_var("RUST_LOG", "example_todos=debug,tower_http=debug")
|
||||
}
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let recorder_handle = setup_metrics_recorder();
|
||||
|
||||
let app = Router::new()
|
||||
.route("/fast", get(|| async {}))
|
||||
.route(
|
||||
"/slow",
|
||||
get(|| async {
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
}),
|
||||
)
|
||||
.route("/metrics", get(move || ready(recorder_handle.render())))
|
||||
.route_layer(middleware::from_fn(track_metrics));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
|
||||
tracing::debug!("listening on {}", addr);
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn setup_metrics_recorder() -> PrometheusHandle {
|
||||
const EXPONENTIAL_SECONDS: &[f64] = &[
|
||||
0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0,
|
||||
];
|
||||
|
||||
let recorder = PrometheusBuilder::new()
|
||||
.set_buckets_for_metric(
|
||||
Matcher::Full("http_requests_duration_seconds".to_string()),
|
||||
EXPONENTIAL_SECONDS,
|
||||
)
|
||||
.build();
|
||||
|
||||
let recorder_handle = recorder.handle();
|
||||
|
||||
metrics::set_boxed_recorder(Box::new(recorder)).unwrap();
|
||||
|
||||
recorder_handle
|
||||
}
|
||||
|
||||
async fn track_metrics<B>(req: Request<B>, next: Next<B>) -> impl IntoResponse {
|
||||
let start = Instant::now();
|
||||
let path = if let Some(matched_path) = req.extensions().get::<MatchedPath>() {
|
||||
matched_path.as_str().to_owned()
|
||||
} else {
|
||||
req.uri().path().to_owned()
|
||||
};
|
||||
let method = req.method().clone();
|
||||
|
||||
let response = next.run(req).await;
|
||||
|
||||
let latency = start.elapsed().as_secs_f64();
|
||||
let status = response.status().as_u16().to_string();
|
||||
|
||||
let labels = [
|
||||
("method", method.to_string()),
|
||||
("path", path),
|
||||
("status", status),
|
||||
];
|
||||
|
||||
metrics::increment_counter!("http_requests_total", &labels);
|
||||
metrics::histogram!("http_requests_duration_seconds", latency, &labels);
|
||||
|
||||
response
|
||||
}
|
Loading…
Reference in a new issue