From c7f34d04c0dbcfece76f3e05165931ee6dac4638 Mon Sep 17 00:00:00 2001 From: durch Date: Mon, 12 May 2025 17:51:34 +0200 Subject: [PATCH] Support submitting to multiple APIs --- nym-network-monitor/Cargo.toml | 2 +- nym-network-monitor/src/accounting.rs | 81 ++++++++++++++------------- nym-network-monitor/src/main.rs | 12 ++-- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/nym-network-monitor/Cargo.toml b/nym-network-monitor/Cargo.toml index c693cb5b19..63d1f37559 100644 --- a/nym-network-monitor/Cargo.toml +++ b/nym-network-monitor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-network-monitor" -version = "1.0.2" +version = "1.1.0" authors.workspace = true repository.workspace = true homepage.workspace = true diff --git a/nym-network-monitor/src/accounting.rs b/nym-network-monitor/src/accounting.rs index 157bbc7c17..97938773e1 100644 --- a/nym-network-monitor/src/accounting.rs +++ b/nym-network-monitor/src/accounting.rs @@ -17,7 +17,7 @@ use tokio::task::JoinHandle; use tokio_postgres::{binary_copy::BinaryCopyInWriter, types::Type, Client, NoTls}; use utoipa::ToSchema; -use crate::{NYM_API_URL, PRIVATE_KEY, TOPOLOGY}; +use crate::{NYM_API_URLS, PRIVATE_KEY, TOPOLOGY}; struct HydratedRoute { mix_nodes: Vec, @@ -491,49 +491,54 @@ pub async fn submit_metrics(database_url: Option<&String>) -> anyhow::Result<()> } if let Some(private_key) = PRIVATE_KEY.get() { - let node_stats = monitor_mixnode_results().await?; - let gateway_stats = monitor_gateway_results().await?; + if let Some(nym_api_urls) = NYM_API_URLS.get() { + for nym_api_url in nym_api_urls { + let node_stats = monitor_mixnode_results().await?; + let gateway_stats = monitor_gateway_results().await?; - info!("Submitting metrics to {}", *NYM_API_URL); - let client = reqwest::Client::new(); + info!("Submitting metrics to {}", nym_api_url); + let client = reqwest::Client::new(); - let node_submit_url = format!("{}/{API_VERSION}/{STATUS}/{SUBMIT_NODE}", &*NYM_API_URL); - let gateway_submit_url = - format!("{}/{API_VERSION}/{STATUS}/{SUBMIT_GATEWAY}", &*NYM_API_URL); + let node_submit_url = + format!("{}/{API_VERSION}/{STATUS}/{SUBMIT_NODE}", nym_api_url); + let gateway_submit_url = + format!("{}/{API_VERSION}/{STATUS}/{SUBMIT_GATEWAY}", nym_api_url); - info!("Submitting {} mixnode measurements", node_stats.len()); + info!("Submitting {} mixnode measurements", node_stats.len()); - node_stats - .chunks(10) - .map(|chunk| { - let monitor_message = MonitorMessage::new(chunk.to_vec(), private_key); - client.post(&node_submit_url).json(&monitor_message).send() - }) - .collect::>() - .collect::>>() - .await - .into_iter() - .collect::, _>>()?; + node_stats + .chunks(10) + .map(|chunk| { + let monitor_message = MonitorMessage::new(chunk.to_vec(), private_key); + client.post(&node_submit_url).json(&monitor_message).send() + }) + .collect::>() + .collect::>>() + .await + .into_iter() + .collect::, _>>()?; - info!("Submitting {} gateway measurements", gateway_stats.len()); + info!("Submitting {} gateway measurements", gateway_stats.len()); - gateway_stats - .chunks(10) - .map(|chunk| { - let monitor_message = MonitorMessage::new( - chunk.to_vec(), - PRIVATE_KEY.get().expect("We've set this!"), - ); - client - .post(&gateway_submit_url) - .json(&monitor_message) - .send() - }) - .collect::>() - .collect::>>() - .await - .into_iter() - .collect::, _>>()?; + gateway_stats + .chunks(10) + .map(|chunk| { + let monitor_message = MonitorMessage::new( + chunk.to_vec(), + PRIVATE_KEY.get().expect("We've set this!"), + ); + client + .post(&gateway_submit_url) + .json(&monitor_message) + .send() + }) + .collect::>() + .collect::>>() + .await + .into_iter() + .collect::, _>>()?; + } + } } NetworkAccount::empty_buffers(); diff --git a/nym-network-monitor/src/main.rs b/nym-network-monitor/src/main.rs index b1cedea18c..5110cc226b 100644 --- a/nym-network-monitor/src/main.rs +++ b/nym-network-monitor/src/main.rs @@ -13,7 +13,6 @@ use nym_sphinx::chunking::monitoring; use nym_topology::{HardcodedTopologyProvider, NymTopology}; use std::fs::File; use std::io::Write; -use std::sync::LazyLock; use std::time::Duration; use std::{ collections::VecDeque, @@ -25,9 +24,7 @@ use tokio::sync::OnceCell; use tokio::{signal::ctrl_c, sync::RwLock}; use tokio_util::sync::CancellationToken; -static NYM_API_URL: LazyLock = LazyLock::new(|| { - std::env::var(NYM_API).unwrap_or_else(|_| panic!("{} env var not set", NYM_API)) -}); +static NYM_API_URLS: OnceCell> = OnceCell::const_new(); static MIXNET_TIMEOUT: OnceCell = OnceCell::const_new(); static TOPOLOGY: OnceCell = OnceCell::const_new(); @@ -138,6 +135,9 @@ struct Args { #[arg(long, env = "DATABASE_URL")] database_url: Option, + + #[arg(long, env = "NYM_APIS")] + nym_apis: Option>, } fn generate_key_pair() -> Result<()> { @@ -200,6 +200,10 @@ async fn main() -> Result<()> { PRIVATE_KEY.set(pk).ok(); } + if let Some(nym_apis) = args.nym_apis { + NYM_API_URLS.set(nym_apis).ok(); + } + TOPOLOGY .set(if let Some(topology_file) = args.topology { NymTopology::new_from_file(topology_file)?