From ad2c5a7f6cfa5b9573ff8074387bec6d30af1e7e Mon Sep 17 00:00:00 2001 From: Valentyn Faychuk Date: Mon, 16 Dec 2024 13:16:42 +0200 Subject: [PATCH] added metrics Signed-off-by: Valentyn Faychuk --- Cargo.lock | 23 +++++++++++++++++++++++ src/datastore.rs | 19 ++++++++++++++++++- src/http_server.rs | 10 ++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index a621eb4..85d12e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2031,6 +2031,8 @@ dependencies = [ "hyper 1.4.1", "hyper-rustls 0.27.3", "hyper-util", + "once_cell", + "prometheus", "prost", "prost-types", "rand 0.8.5", @@ -3226,6 +3228,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prometheus" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "protobuf", + "thiserror", +] + [[package]] name = "prost" version = "0.13.3" @@ -3279,6 +3296,12 @@ dependencies = [ "prost", ] +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + [[package]] name = "qstring" version = "0.7.2" diff --git a/src/datastore.rs b/src/datastore.rs index d75ff09..f7caab4 100644 --- a/src/datastore.rs +++ b/src/datastore.rs @@ -2,7 +2,7 @@ use crate::persistence::{Logfile, SealError, SealedFile}; use dashmap::{DashMap, DashSet}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, TimestampSeconds}; -use std::time::{Duration, SystemTime}; +use std::time::{Duration, SystemTime, UNIX_EPOCH}; type IP = String; pub const LOCALHOST: &str = "localhost"; @@ -34,6 +34,23 @@ impl NodeInfo { serde_json::to_string(self).unwrap() // can fail only if time goes backwards :D } + pub fn to_metrics(&self, ip: &str) -> String { + let started_at = self.started_at.duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO); + let keepalive = self.keepalive.duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO); + let labels = format!("{{ip=\"{}\", public=\"{}\"}}", ip, self.public); + + let mut res = String::new(); + res.push_str(&format!("started_at{} {}\n", labels, started_at.as_secs())); + res.push_str(&format!("keepalive{} {}\n", labels, keepalive.as_secs())); + res.push_str(&format!("mint_requests{} {}\n", labels, self.mint_requests)); + res.push_str(&format!("mints{} {}\n", labels, self.mints)); + res.push_str(&format!("mratls_conns{} {}\n", labels, self.mratls_conns)); + res.push_str(&format!("net_attacks{} {}\n", labels, self.net_attacks)); + res.push_str(&format!("restarts{} {}\n", labels, self.restarts)); + res.push_str(&format!("disk_attacks{} {}\n", labels, self.disk_attacks)); + res + } + pub fn log(&self, ip: &IP) { let json = format!("{{\"ip\":\"{}\",", ip) + &self.to_json()[1..]; if let Err(e) = Logfile::append(LOG_PATH, &format!("{}\n", &json)) { diff --git a/src/http_server.rs b/src/http_server.rs index 97dbf85..b4f8aaa 100644 --- a/src/http_server.rs +++ b/src/http_server.rs @@ -78,6 +78,15 @@ async fn mint( } } +#[get("/metrics")] +async fn metrics(ds: web::Data>) -> HttpResponse { + let mut metrics = String::new(); + for (ip, node) in ds.get_node_list() { + metrics.push_str(node.to_metrics(&ip).as_str()); + } + HttpResponse::Ok().content_type("text/plain; version=0.0.4; charset=utf-8").body(metrics) +} + pub async fn init(state: Arc, sol_client: Arc) { HttpServer::new(move || { App::new() @@ -86,6 +95,7 @@ pub async fn init(state: Arc, sol_client: Arc) { .service(homepage) .service(get_nodes) .service(mint) + .service(metrics) }) .bind("0.0.0.0:31372") .unwrap()