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