Skip to content

Commit afa6eae

Browse files
committed
chore(examples): add axum example
Signed-off-by: Jerry Wang <[email protected]>
1 parent 53f15ec commit afa6eae

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ prost-types = { version = "0.12.0", optional = true }
2727

2828
[dev-dependencies]
2929
async-std = { version = "1", features = ["attributes"] }
30+
axum = "0.7"
3031
criterion = "0.5"
3132
http-types = "2"
3233
pyo3 = "0.21"

examples/axum.rs

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use axum::body::Body;
2+
use axum::extract::State;
3+
use axum::http::header::CONTENT_TYPE;
4+
use axum::http::StatusCode;
5+
use axum::response::{IntoResponse, Response};
6+
use axum::routing::get;
7+
use axum::Router;
8+
use prometheus_client::encoding::text::encode;
9+
use prometheus_client::metrics::counter::Counter;
10+
use prometheus_client::metrics::family::Family;
11+
use prometheus_client::registry::Registry;
12+
use prometheus_client_derive_encode::{EncodeLabelSet, EncodeLabelValue};
13+
use std::sync::Arc;
14+
use tokio::sync::Mutex;
15+
16+
#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelValue)]
17+
pub enum Method {
18+
Get,
19+
Post,
20+
}
21+
22+
#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
23+
pub struct MethodLabels {
24+
pub method: Method,
25+
}
26+
27+
#[derive(Debug)]
28+
pub struct Metrics {
29+
requests: Family<MethodLabels, Counter>,
30+
}
31+
32+
impl Metrics {
33+
pub fn inc_requests(&self, method: Method) {
34+
self.requests.get_or_create(&MethodLabels { method }).inc();
35+
}
36+
}
37+
38+
#[derive(Debug)]
39+
pub struct AppState {
40+
pub registry: Registry,
41+
}
42+
43+
pub async fn metrics_handler(State(state): State<Arc<Mutex<AppState>>>) -> impl IntoResponse {
44+
let state = state.lock().await;
45+
let mut buffer = String::new();
46+
encode(&mut buffer, &state.registry).unwrap();
47+
48+
Response::builder()
49+
.status(StatusCode::OK)
50+
.header(
51+
CONTENT_TYPE,
52+
"application/openmetrics-text; version=1.0.0; charset=utf-8",
53+
)
54+
.body(Body::from(buffer))
55+
.unwrap()
56+
}
57+
58+
pub async fn some_handler(State(metrics): State<Arc<Mutex<Metrics>>>) -> impl IntoResponse {
59+
metrics.lock().await.inc_requests(Method::Get);
60+
"okay".to_string()
61+
}
62+
63+
#[tokio::main]
64+
async fn main() {
65+
let metrics = Metrics {
66+
requests: Family::default(),
67+
};
68+
let mut state = AppState {
69+
registry: Registry::default(),
70+
};
71+
state
72+
.registry
73+
.register("requests", "Count of requests", metrics.requests.clone());
74+
let metrics = Arc::new(Mutex::new(metrics));
75+
let state = Arc::new(Mutex::new(state));
76+
77+
let router = Router::new()
78+
.route("/metrics", get(metrics_handler))
79+
.with_state(state)
80+
.route("/handler", get(some_handler))
81+
.with_state(metrics);
82+
let port = 8080;
83+
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", port))
84+
.await
85+
.unwrap();
86+
87+
axum::serve(listener, router).await.unwrap();
88+
}

0 commit comments

Comments
 (0)