Merge pull request #4484 from nymtech/more-metrics

Expose metrics from PacketStatisticsControl
This commit is contained in:
Tommy Verrall
2024-03-20 12:43:17 +00:00
committed by GitHub
9 changed files with 392 additions and 62 deletions
Generated
+107 -35
View File
@@ -557,9 +557,9 @@ dependencies = [
"bitflags 1.3.2",
"bytes",
"futures-util",
"http",
"http-body",
"hyper",
"http 0.2.9",
"http-body 0.4.5",
"hyper 0.14.27",
"itoa",
"matchit",
"memchr",
@@ -587,8 +587,8 @@ dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http-body",
"http 0.2.9",
"http-body 0.4.5",
"mime",
"rustversion",
"tower-layer",
@@ -3011,7 +3011,7 @@ dependencies = [
"futures-core",
"futures-sink",
"gloo-utils",
"http",
"http 0.2.9",
"js-sys",
"pin-project",
"serde",
@@ -3080,7 +3080,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http",
"http 0.2.9",
"indexmap 1.9.3",
"slab",
"tokio",
@@ -3290,6 +3290,17 @@ dependencies = [
"itoa",
]
[[package]]
name = "http"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-api-client"
version = "0.1.0"
@@ -3311,7 +3322,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
"http 0.2.9",
"pin-project-lite 0.2.13",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http 1.1.0",
]
[[package]]
name = "http-body-util"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d"
dependencies = [
"bytes",
"futures-core",
"http 1.1.0",
"http-body 1.0.0",
"pin-project-lite 0.2.13",
]
@@ -3379,8 +3413,8 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"http 0.2.9",
"http-body 0.4.5",
"httparse",
"httpdate",
"itoa",
@@ -3392,6 +3426,25 @@ dependencies = [
"want",
]
[[package]]
name = "hyper"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"httparse",
"httpdate",
"itoa",
"pin-project-lite 0.2.13",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-rustls"
version = "0.24.1"
@@ -3399,8 +3452,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97"
dependencies = [
"futures-util",
"http",
"hyper",
"http 0.2.9",
"hyper 0.14.27",
"rustls 0.21.10",
"tokio",
"tokio-rustls 0.24.1",
@@ -3412,12 +3465,28 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
dependencies = [
"hyper",
"hyper 0.14.27",
"pin-project-lite 0.2.13",
"tokio",
"tokio-io-timeout",
]
[[package]]
name = "hyper-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
dependencies = [
"bytes",
"futures-util",
"http 1.1.0",
"http-body 1.0.0",
"hyper 1.2.0",
"pin-project-lite 0.2.13",
"socket2 0.5.4",
"tokio",
]
[[package]]
name = "iana-time-zone"
version = "0.1.58"
@@ -3742,7 +3811,7 @@ dependencies = [
"curl-sys",
"event-listener",
"futures-lite",
"http",
"http 0.2.9",
"log",
"once_cell",
"polling",
@@ -4555,7 +4624,7 @@ dependencies = [
"bytes",
"encoding_rs",
"futures-util",
"http",
"http 0.2.9",
"httparse",
"log",
"memchr",
@@ -5192,7 +5261,10 @@ dependencies = [
"dirs 4.0.0",
"futures",
"gloo-timers",
"http-body-util",
"humantime-serde",
"hyper 1.2.0",
"hyper-util",
"log",
"nym-bandwidth-controller",
"nym-config",
@@ -5201,6 +5273,7 @@ dependencies = [
"nym-explorer-client",
"nym-gateway-client",
"nym-gateway-requests",
"nym-metrics",
"nym-network-defaults",
"nym-nonexhaustive-delayqueue",
"nym-pemstore",
@@ -5514,7 +5587,7 @@ dependencies = [
"dotenvy",
"futures",
"humantime-serde",
"hyper",
"hyper 0.14.27",
"ipnetwork 0.16.0",
"log",
"nym-api-requests",
@@ -5719,7 +5792,6 @@ dependencies = [
"lazy_static",
"log",
"prometheus",
"regex",
]
[[package]]
@@ -5950,7 +6022,7 @@ dependencies = [
"dashmap",
"fastrand 2.0.1",
"hmac 0.12.1",
"hyper",
"hyper 0.14.27",
"ipnetwork 0.16.0",
"mime",
"nym-config",
@@ -6103,7 +6175,7 @@ dependencies = [
"dotenvy",
"futures",
"hex",
"http",
"http 0.2.9",
"httpcodec",
"libp2p",
"log",
@@ -6843,7 +6915,7 @@ checksum = "a819b71d6530c4297b49b3cae2939ab3a8cc1b9f382826a1bc29dd0ca3864906"
dependencies = [
"async-trait",
"bytes",
"http",
"http 0.2.9",
"isahc",
"opentelemetry_api",
]
@@ -6857,7 +6929,7 @@ dependencies = [
"async-trait",
"futures",
"futures-executor",
"http",
"http 0.2.9",
"isahc",
"once_cell",
"opentelemetry",
@@ -8038,9 +8110,9 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"http 0.2.9",
"http-body 0.4.5",
"hyper 0.14.27",
"hyper-rustls",
"ipnet",
"js-sys",
@@ -8199,7 +8271,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69"
dependencies = [
"http",
"http 0.2.9",
"log",
"regex",
"rocket",
@@ -8219,8 +8291,8 @@ dependencies = [
"cookie",
"either",
"futures",
"http",
"hyper",
"http 0.2.9",
"hyper 0.14.27",
"indexmap 2.0.2",
"log",
"memchr",
@@ -9024,9 +9096,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.1"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
[[package]]
name = "snafu"
@@ -9978,9 +10050,9 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http-body",
"hyper",
"http 0.2.9",
"http-body 0.4.5",
"hyper 0.14.27",
"hyper-timeout",
"percent-encoding",
"pin-project",
@@ -10023,8 +10095,8 @@ dependencies = [
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http 0.2.9",
"http-body 0.4.5",
"http-range-header",
"httpdate",
"mime",
@@ -10302,7 +10374,7 @@ dependencies = [
"byteorder",
"bytes",
"data-encoding",
"http",
"http 0.2.9",
"httparse",
"log",
"rand 0.8.5",
+21 -3
View File
@@ -27,7 +27,7 @@ tap = "1.0.1"
thiserror = { workspace = true }
url = { workspace = true, features = ["serde"] }
tungstenite = { workspace = true, default-features = false }
tokio = { workspace = true, features = ["macros"]}
tokio = { workspace = true, features = ["macros"] }
time = "0.3.17"
zeroize = { workspace = true }
@@ -38,6 +38,7 @@ nym-crypto = { path = "../crypto" }
nym-explorer-client = { path = "../../explorer-api/explorer-client" }
nym-gateway-client = { path = "../client-libs/gateway-client" }
nym-gateway-requests = { path = "../../gateway/gateway-requests" }
nym-metrics = { path = "../nym-metrics" }
nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" }
nym-sphinx = { path = "../nymsphinx" }
nym-pemstore = { path = "../pemstore" }
@@ -48,6 +49,19 @@ nym-credential-storage = { path = "../credential-storage" }
nym-network-defaults = { path = "../network-defaults" }
si-scale = "0.2.2"
### For serving prometheus metrics
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper]
version = "1"
features = ["server", "http1"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.http-body-util]
version = "0.1"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper-util]
version = "0.1"
features = ["tokio"]
###
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
version = "0.1.11"
features = ["time"]
@@ -91,11 +105,15 @@ tempfile = "3.1.0"
[build-dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
"sqlite",
"macros",
"migrate",
] }
[features]
default = []
cli = ["clap"]
fs-surb-storage = ["sqlx"]
wasm = ["nym-gateway-client/wasm"]
@@ -3,8 +3,30 @@ use std::{
time::{Duration, Instant},
};
use log::{info, warn};
use nym_metrics::{inc, inc_by, metrics};
use si_scale::helpers::bibytes2;
// Metrics server
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use http_body_util::Full;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::body::Bytes;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::server::conn::http1;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::service::service_fn;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper::{Request, Response};
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use hyper_util::rt::TokioIo;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use std::convert::Infallible;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use std::net::SocketAddr;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
use tokio::net::TcpListener;
use crate::spawn_future;
// Time interval between reporting packet statistics
@@ -53,42 +75,60 @@ impl PacketStatistics {
PacketStatisticsEvent::RealPacketSent(packet_size) => {
self.real_packets_sent += 1;
self.real_packets_sent_size += packet_size;
inc!("real_packets_sent");
inc_by!("real_packets_sent_size", packet_size);
}
PacketStatisticsEvent::CoverPacketSent(packet_size) => {
self.cover_packets_sent += 1;
self.cover_packets_sent_size += packet_size;
inc!("cover_packets_sent");
inc_by!("cover_packets_sent_size", packet_size);
}
PacketStatisticsEvent::RealPacketReceived(packet_size) => {
self.real_packets_received += 1;
self.real_packets_received_size += packet_size;
inc!("real_packets_received");
inc_by!("real_packets_received_size", packet_size);
}
PacketStatisticsEvent::CoverPacketReceived(packet_size) => {
self.cover_packets_received += 1;
self.cover_packets_received_size += packet_size;
inc!("cover_packets_received");
inc_by!("cover_packets_received_size", packet_size);
}
PacketStatisticsEvent::AckReceived(packet_size) => {
self.total_acks_received += 1;
self.total_acks_received_size += packet_size;
inc!("total_acks_received");
inc_by!("total_acks_received_size", packet_size);
}
PacketStatisticsEvent::RealAckReceived(packet_size) => {
self.real_acks_received += 1;
self.real_acks_received_size += packet_size;
inc!("real_acks_received");
inc_by!("real_acks_received_size", packet_size);
}
PacketStatisticsEvent::CoverAckReceived(packet_size) => {
self.cover_acks_received += 1;
self.cover_acks_received_size += packet_size;
inc!("cover_acks_received");
inc_by!("cover_acks_received_size", packet_size);
}
PacketStatisticsEvent::RealPacketQueued => {
self.real_packets_queued += 1;
inc!("real_packets_queued");
}
PacketStatisticsEvent::RetransmissionQueued => {
self.retransmissions_queued += 1;
inc!("retransmissions_queued");
}
PacketStatisticsEvent::ReplySurbRequestQueued => {
self.reply_surbs_queued += 1;
inc!("reply_surbs_queued");
}
PacketStatisticsEvent::AdditionalReplySurbRequestQueued => {
self.additional_reply_surbs_queued += 1;
inc!("additional_reply_surbs_queued");
}
}
}
@@ -465,6 +505,33 @@ impl PacketStatisticsControl {
let snapshot_interval = Duration::from_millis(SNAPSHOT_INTERVAL_MS);
let mut snapshot_interval = tokio::time::interval(snapshot_interval);
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
log::warn!("Metrics server is not supported on wasm32-unknown-unknown");
let listener = None;
} else {
let mut metrics_port = 18000;
let listener: Option<TcpListener>;
loop {
let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port));
match TcpListener::bind(addr).await {
Ok(l) => {
info!("###############################");
info!("Metrics endpoint is at: {:?}", l.local_addr());
info!("###############################");
listener = Some(l);
break;
},
Err(err) => {
log::warn!("Failed to bind metrics server: {:?}", err);
metrics_port += 1;
}
};
}
}
}
loop {
tokio::select! {
stats_event = self.stats_rx.recv() => match stats_event {
@@ -477,6 +544,27 @@ impl PacketStatisticsControl {
break;
}
},
// conditional will disable the branch if we're in wasm32-unknown-unknown
result = listener.as_ref().unwrap().accept(), if listener.is_some() => {
cfg_if::cfg_if! {
if #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] {
if let Ok((stream, _)) = result {
let io = TokioIo::new(stream);
tokio::task::spawn(async move {
if let Err(err) = http1::Builder::new()
.serve_connection(io, service_fn(serve_metrics))
.await
{
warn!("Error serving connection: {:?}", err);
}
});
} else {
warn!("Error accepting connection");
}
}
}
}
_ = snapshot_interval.tick() => {
self.update_history();
self.update_rates();
@@ -501,3 +589,9 @@ impl PacketStatisticsControl {
})
}
}
async fn serve_metrics(
_: Request<hyper::body::Incoming>,
) -> Result<Response<Full<Bytes>>, Infallible> {
Ok(Response::new(Full::new(Bytes::from(metrics!()))))
}
-1
View File
@@ -14,5 +14,4 @@ license.workspace = true
prometheus = { workspace = true }
log = { workspace = true }
dashmap = { workspace = true }
regex = "1.1"
lazy_static = "1.4"
+111 -13
View File
@@ -1,12 +1,47 @@
use dashmap::DashMap;
pub use log::error;
use log::{debug, warn};
use regex::Regex;
use std::fmt;
pub use std::time::Instant;
use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder};
#[macro_export]
macro_rules! prepend_package_name {
($name: literal) => {
&format!(
"{}_{}",
std::module_path!()
.split("::")
.next()
.unwrap_or("x")
.to_string(),
$name
)
};
}
#[macro_export]
macro_rules! inc_by {
($name:literal, $x:expr) => {
$crate::REGISTRY.inc_by($crate::prepend_package_name!($name), $x as f64);
};
}
#[macro_export]
macro_rules! inc {
($name:literal) => {
$crate::REGISTRY.inc($crate::prepend_package_name!($name));
};
}
#[macro_export]
macro_rules! metrics {
() => {
$crate::REGISTRY.to_string();
};
}
#[macro_export]
macro_rules! nanos {
( $name:literal, $x:expr ) => {{
@@ -14,13 +49,13 @@ macro_rules! nanos {
// if the block needs to return something, we can return it
let r = $x;
let duration = start.elapsed().as_nanos() as f64;
let name = $crate::prepend_package_name!($name);
$crate::REGISTRY.inc_by(&format!("{}_nanos", $name), duration);
r
}};
}
lazy_static::lazy_static! {
pub static ref RE: Regex = Regex::new(r"[^a-zA-Z0-9_]").unwrap();
pub static ref REGISTRY: MetricsController = MetricsController::default();
}
@@ -43,6 +78,7 @@ fn fq_name(c: &dyn Collector) -> String {
}
impl Metric {
#[inline(always)]
fn fq_name(&self) -> String {
match self {
Metric::C(c) => fq_name(c.as_ref()),
@@ -50,6 +86,15 @@ impl Metric {
}
}
#[inline(always)]
fn inc(&self) {
match self {
Metric::C(c) => c.inc(),
Metric::G(g) => g.inc(),
}
}
#[inline(always)]
fn inc_by(&self, value: f64) {
match self {
Metric::C(c) => c.inc_by(value),
@@ -57,6 +102,7 @@ impl Metric {
}
}
#[inline(always)]
fn set(&self, value: f64) {
match self {
Metric::C(_c) => {
@@ -69,14 +115,8 @@ impl Metric {
impl fmt::Display for MetricsController {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buffer = vec![];
let encoder = TextEncoder::new();
let metrics = self.registry.gather();
match encoder.encode(&metrics, &mut buffer) {
Ok(_) => {}
Err(e) => return write!(f, "Error encoding metrics to buffer: {}", e),
}
let output = match String::from_utf8(buffer) {
let metrics = self.gather();
let output = match String::from_utf8(metrics) {
Ok(output) => output,
Err(e) => return write!(f, "Error decoding metrics to String: {}", e),
};
@@ -85,6 +125,26 @@ impl fmt::Display for MetricsController {
}
impl MetricsController {
#[inline(always)]
pub fn gather(&self) -> Vec<u8> {
let mut buffer = vec![];
let encoder = TextEncoder::new();
let metrics = self.registry.gather();
match encoder.encode(&metrics, &mut buffer) {
Ok(_) => {}
Err(e) => error!("Error encoding metrics to buffer: {}", e),
}
buffer
}
pub fn to_writer(&self, writer: &mut dyn std::io::Write) {
let metrics = self.gather();
match writer.write_all(&metrics) {
Ok(_) => {}
Err(e) => error!("Error writing metrics to writer: {}", e),
}
}
pub fn set(&self, name: &str, value: f64) {
if let Some(metric) = self.registry_index.get(name) {
metric.set(value);
@@ -101,6 +161,22 @@ impl MetricsController {
}
}
pub fn inc(&self, name: &str) {
if let Some(metric) = self.registry_index.get(name) {
metric.inc();
} else {
let counter = match Counter::new(sanitize_metric_name(name), name) {
Ok(c) => c,
Err(e) => {
debug!("Failed to create counter {:?}:\n{}", name, e);
return;
}
};
self.register_counter(Box::new(counter));
self.inc(name)
}
}
pub fn inc_by(&self, name: &str, value: f64) {
if let Some(metric) = self.registry_index.get(name) {
metric.inc_by(value);
@@ -161,9 +237,31 @@ impl MetricsController {
}
}
#[inline(always)]
fn sanitize_metric_name(name: &str) -> String {
RE.replace_all(name, "_").to_string()
// The first character must be [a-zA-Z_:], and all subsequent characters must be [a-zA-Z0-9_:].
let mut out = String::with_capacity(name.len());
let mut is_invalid: fn(char) -> bool = invalid_metric_name_start_character;
for c in name.chars() {
if is_invalid(c) {
out.push('_');
} else {
out.push(c);
}
is_invalid = invalid_metric_name_character;
}
out
}
#[inline]
fn invalid_metric_name_start_character(c: char) -> bool {
// Essentially, needs to match the regex pattern of [a-zA-Z_:].
!(c.is_ascii_alphabetic() || c == '_' || c == ':')
}
#[inline]
fn invalid_metric_name_character(c: char) -> bool {
// Essentially, needs to match the regex pattern of [a-zA-Z0-9_:].
!(c.is_ascii_alphanumeric() || c == '_' || c == ':')
}
#[cfg(test)]
@@ -174,7 +272,7 @@ mod tests {
fn test_sanitization() {
assert_eq!(
sanitize_metric_name("packets_sent_34.242.65.133:1789"),
"packets_sent_34_242_65_133_1789"
"packets_sent_34_242_65_133:1789"
)
}
}
+3 -3
View File
@@ -7,7 +7,7 @@ use axum::{
extract::{Query, State},
http::HeaderMap,
};
use nym_metrics::REGISTRY;
use nym_metrics::metrics;
use nym_node::http::api::{FormattedResponse, Output};
use serde::{Deserialize, Serialize};
@@ -24,7 +24,7 @@ pub(crate) async fn metrics(State(state): State<MixnodeAppState>, headers: Heade
if let Some(metrics_key) = state.metrics_key {
if let Some(auth) = headers.get("Authorization") {
if auth.to_str().unwrap_or_default() == format!("Bearer {}", metrics_key) {
REGISTRY.to_string()
metrics!()
} else {
"Unauthorized".to_string()
}
@@ -50,7 +50,7 @@ pub(crate) async fn stats(
async fn generate_stats(full: bool, stats: SharedNodeStats) -> NodeStatsResponse {
let snapshot_data = stats.clone_data().await;
if full {
NodeStatsResponse::Full(REGISTRY.to_string())
NodeStatsResponse::Full(metrics!())
} else {
NodeStatsResponse::Simple(snapshot_data.simplify())
}
+10 -6
View File
@@ -1,7 +1,7 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use nym_metrics::REGISTRY;
use nym_metrics::inc_by;
use super::TaskClient;
use futures::channel::mpsc;
@@ -65,11 +65,14 @@ impl SharedNodeStats {
guard.packets_dropped_since_startup_all += count;
}
REGISTRY.inc_by("packets_received_since_startup", new_received);
REGISTRY.inc_by("packets_sent_since_startup_all", new_sent.values().sum());
REGISTRY.inc_by(
inc_by!("packets_received_since_startup", new_received);
inc_by!(
"packets_sent_since_startup_all",
new_sent.values().sum::<f64>()
);
inc_by!(
"packets_dropped_since_startup_all",
new_dropped.values().sum(),
new_dropped.values().sum::<f64>()
);
guard.packets_received_since_last_update = new_received;
@@ -509,6 +512,7 @@ impl Controller {
#[cfg(test)]
mod tests {
use super::*;
use nym_metrics::metrics;
use nym_task::TaskManager;
#[tokio::test]
@@ -538,6 +542,6 @@ mod tests {
assert_eq!(&stats.packets_sent_since_last_update.len(), &1);
assert_eq!(&stats.packets_received_since_startup, &0.);
assert_eq!(&stats.packets_dropped_since_startup_all, &0.);
assert_eq!(REGISTRY.to_string(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n")
assert_eq!(metrics!(), "# HELP nym_mixnode_packets_dropped_since_startup_all nym_mixnode_packets_dropped_since_startup_all\n# TYPE nym_mixnode_packets_dropped_since_startup_all counter\nnym_mixnode_packets_dropped_since_startup_all 0\n# HELP nym_mixnode_packets_received_since_startup nym_mixnode_packets_received_since_startup\n# TYPE nym_mixnode_packets_received_since_startup counter\nnym_mixnode_packets_received_since_startup 0\n# HELP nym_mixnode_packets_sent_since_startup_all nym_mixnode_packets_sent_since_startup_all\n# TYPE nym_mixnode_packets_sent_since_startup_all counter\nnym_mixnode_packets_sent_since_startup_all 2\n")
}
}
+3 -1
View File
@@ -72,7 +72,9 @@ def config_to_targets(config, mixnodes, labels=None):
def make_prom_target(env, mixnode, port=None, labels=None):
bond_info = mixnode.get("bond_information", {})
mix_node = bond_info.get("mix_node", {})
mix_node = bond_info.get("mix_node")
if mix_node is None:
mix_node = mixnode.get("gateway")
host = mix_node.get("host", None)
port = port if port else mix_node.get("http_api_port", None)
if host is None or port is None:
+43
View File
@@ -0,0 +1,43 @@
import json
import os
ips = [
"2.221.182.179",
"54.232.20.104",
"15.237.112.155",
"54.93.108.209",
"13.38.74.100",
"15.237.93.154",
"18.156.175.57",
"3.76.123.170",
]
port_range = range(18000, 18999)
def make_prom_target(ip, port, env):
return {
"targets": [f"{ip}:{port}"],
"labels": {
"mixnet_env": env,
},
}
if __name__ == "__main__":
outfile = "/tmp/tmp_static_prom_tragets.json"
outlink = "/tmp/static_prom_tragets.json"
targets = []
for ip in ips:
for port in port_range:
targets.append(make_prom_target(ip, port, "performance"))
with open(outfile, "w") as f:
json.dump(targets, f)
os.chmod(outfile, 0o777)
os.rename(outfile, outlink)
os.chmod(outlink, 0o777)
print(f"Prometheus -> {len(targets)} targets written to {outlink}")