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
use axum::{http::StatusCode, routing::get, Extension, Router};
use config::WorkerId;
use crypto::PublicKey;
use multiaddr::Multiaddr;
use mysten_network::multiaddr::to_socket_addr;
use prometheus::{Registry, TextEncoder};
use std::collections::HashMap;
use tokio::task::JoinHandle;
const METRICS_ROUTE: &str = "/metrics";
const PRIMARY_METRICS_PREFIX: &str = "narwhal_primary";
const WORKER_METRICS_PREFIX: &str = "narwhal_worker";
pub fn primary_metrics_registry(name: PublicKey) -> Registry {
let mut labels = HashMap::new();
labels.insert("node_name".to_string(), name.to_string());
Registry::new_custom(Some(PRIMARY_METRICS_PREFIX.to_string()), Some(labels)).unwrap()
}
pub fn worker_metrics_registry(worker_id: WorkerId, name: PublicKey) -> Registry {
let mut labels = HashMap::new();
labels.insert("node_name".to_string(), name.to_string());
labels.insert("worker_id".to_string(), worker_id.to_string());
Registry::new_custom(Some(WORKER_METRICS_PREFIX.to_string()), Some(labels)).unwrap()
}
#[must_use]
pub fn start_prometheus_server(addr: Multiaddr, registry: &Registry) -> JoinHandle<()> {
let app = Router::new()
.route(METRICS_ROUTE, get(metrics))
.layer(Extension(registry.clone()));
let socket_addr = to_socket_addr(&addr).expect("failed to convert Multiaddr to SocketAddr");
tokio::spawn(async move {
axum::Server::bind(&socket_addr)
.serve(app.into_make_service())
.await
.unwrap();
})
}
async fn metrics(registry: Extension<Registry>) -> (StatusCode, String) {
let metrics_families = registry.gather();
match TextEncoder.encode_to_string(&metrics_families) {
Ok(metrics) => (StatusCode::OK, metrics),
Err(error) => (
StatusCode::INTERNAL_SERVER_ERROR,
format!("unable to encode metrics: {error}"),
),
}
}