Compare commits

...

3 Commits

Author SHA1 Message Date
977bc63c54 fix: some counters not getting used 2025-07-19 18:45:01 -04:00
54f7810b27 chore: cleanup some rust stuff 2025-07-19 18:43:07 -04:00
24e49c14b7 fix: metrics api changes 2025-07-19 18:25:41 -04:00
6 changed files with 54 additions and 103 deletions

52
Cargo.lock generated
View File

@ -17,17 +17,6 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "ahash"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9"
dependencies = [
"getrandom 0.2.16",
"once_cell",
"version_check",
]
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.8.12" version = "0.8.12"
@ -260,7 +249,7 @@ dependencies = [
"anyhow", "anyhow",
"gflags", "gflags",
"icmp-socket", "icmp-socket",
"metrics 0.20.1", "metrics",
"metrics-exporter-prometheus", "metrics-exporter-prometheus",
"nursery", "nursery",
"resolve", "resolve",
@ -708,25 +697,14 @@ version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "metrics"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b9b8653cec6897f73b519a43fba5ee3d50f62fe9af80b428accdcc093b4a849"
dependencies = [
"ahash 0.7.8",
"metrics-macros",
"portable-atomic 0.3.20",
]
[[package]] [[package]]
name = "metrics" name = "metrics"
version = "0.24.2" version = "0.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5" checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5"
dependencies = [ dependencies = [
"ahash 0.8.12", "ahash",
"portable-atomic 1.11.1", "portable-atomic",
] ]
[[package]] [[package]]
@ -742,7 +720,7 @@ dependencies = [
"hyper-util", "hyper-util",
"indexmap", "indexmap",
"ipnet", "ipnet",
"metrics 0.24.2", "metrics",
"metrics-util", "metrics-util",
"quanta", "quanta",
"thiserror", "thiserror",
@ -750,17 +728,6 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "metrics-macros"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "731f8ecebd9f3a4aa847dfe75455e4757a45da40a7793d2f0b1f9b6ed18b23f3"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "metrics-util" name = "metrics-util"
version = "0.20.0" version = "0.20.0"
@ -770,7 +737,7 @@ dependencies = [
"crossbeam-epoch", "crossbeam-epoch",
"crossbeam-utils", "crossbeam-utils",
"hashbrown", "hashbrown",
"metrics 0.24.2", "metrics",
"quanta", "quanta",
"rand 0.9.1", "rand 0.9.1",
"rand_xoshiro", "rand_xoshiro",
@ -868,15 +835,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "portable-atomic"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e30165d31df606f5726b090ec7592c308a0eaf61721ff64c9a3018e344a8753e"
dependencies = [
"portable-atomic 1.11.1",
]
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.11.1" version = "1.11.1"

View File

@ -12,7 +12,7 @@ tracing-subscriber = "0.3.14"
anyhow = "1" anyhow = "1"
gflags = "^0.3" gflags = "^0.3"
nursery = "^0.0.1" nursery = "^0.0.1"
metrics = "0.20.1" metrics = "0.24.2"
metrics-exporter-prometheus = "0.17.2" metrics-exporter-prometheus = "0.17.2"
tiny_http = "0.12.0" tiny_http = "0.12.0"
socket2 = "0.5.1" socket2 = "0.5.1"

View File

@ -9,14 +9,14 @@
flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
}; };
outputs = {self, flake-utils, naersk, flake-compat, nixpkgs}: outputs = {self, flake-utils, naersk, ...}:
flake-utils.lib.eachDefaultSystem (system: flake-utils.lib.eachDefaultSystem (system:
let let
naersk-lib = naersk.lib."${system}"; naersk-lib = naersk.lib."${system}";
in in
{ {
defaultPackage = naersk-lib.buildPackage rec { defaultPackage = naersk-lib.buildPackage {
pname = "kitchen"; pname = "durnitisp";
src = ./.; src = ./.;
}; };
} }

View File

@ -25,7 +25,7 @@ use icmp_socket::{
packet::{Icmpv4Message, Icmpv6Message, WithEchoRequest}, packet::{Icmpv4Message, Icmpv6Message, WithEchoRequest},
IcmpSocket, IcmpSocket4, IcmpSocket6, Icmpv4Packet, Icmpv6Packet, IcmpSocket, IcmpSocket4, IcmpSocket6, Icmpv4Packet, Icmpv6Packet,
}; };
use metrics::{gauge, histogram, increment_counter, Label}; use metrics::{counter, gauge, histogram, Label};
use nursery::{thread, Nursery}; use nursery::{thread, Nursery};
use tracing::{debug, error, info, instrument, warn}; use tracing::{debug, error, info, instrument, warn};
@ -89,18 +89,20 @@ impl<AddrType: std::fmt::Display> State<AddrType> {
seq = sequence, seq = sequence,
"Reply", "Reply",
); );
increment_counter!("ping_counter", make_ping_count_labels(domain_name, "ok"),); let ping_counter = counter!("ping_counter", make_ping_count_labels(domain_name, "ok"),);
ping_counter.increment(1);
if elapsed as i32 != 0 { if elapsed as i32 != 0 {
gauge!( let ping_latency = gauge!(
"ping_latency", "ping_latency",
elapsed,
vec![Label::new("domain", domain_name.to_owned()),], vec![Label::new("domain", domain_name.to_owned()),],
); );
histogram!( ping_latency.set(elapsed);
let ping_latency_hist_ms = histogram!(
"ping_latency_hist_ms", "ping_latency_hist_ms",
elapsed,
vec![Label::new("domain", domain_name.to_owned()),], vec![Label::new("domain", domain_name.to_owned()),],
); );
ping_latency_hist_ms.record(elapsed);
} }
self.time_tracker self.time_tracker
.get_mut(&identifier) .get_mut(&identifier)
@ -124,10 +126,10 @@ impl<AddrType: std::fmt::Display> State<AddrType> {
seq = *k, seq = *k,
"Dropped" "Dropped"
); );
increment_counter!( counter!(
"ping_counter", "ping_counter",
make_ping_count_labels(domain_name, "dropped"), make_ping_count_labels(domain_name, "dropped"),
); ).increment(1);
for_delete.push(*k); for_delete.push(*k);
} }
} }
@ -186,10 +188,10 @@ impl<'a> PacketHandler<Icmpv6Packet, Ipv6Addr> for &'a mut State<Ipv6Addr> {
}, },
}) => { }) => {
if let Some((domain_name, _addr)) = self.destinations.get(&identifier) { if let Some((domain_name, _addr)) = self.destinations.get(&identifier) {
increment_counter!( counter!(
"ping_counter", "ping_counter",
make_ping_count_labels(domain_name, "unreachable") make_ping_count_labels(domain_name, "unreachable")
); ).increment(1);
return true; return true;
} }
} }
@ -299,7 +301,7 @@ where
); );
match self.send_to_destination(dest, identifier, sequence) { match self.send_to_destination(dest, identifier, sequence) {
Err(e) => { Err(e) => {
increment_counter!("ping_counter", make_ping_count_labels(domain_name, "err"),); counter!("ping_counter", make_ping_count_labels(domain_name, "err"),).increment(1);
error!( error!(
domain=domain_name, %dest, err=?e, domain=domain_name, %dest, err=?e,
"Error sending. Trying again later", "Error sending. Trying again later",
@ -392,7 +394,7 @@ where
} }
Err(e) => { Err(e) => {
error!(err = ?e, "Error receiving packet"); error!(err = ?e, "Error receiving packet");
increment_counter!("ping_counter", make_ping_count_labels("unknown", "err"),); counter!("ping_counter", make_ping_count_labels("unknown", "err"),).increment(1);
return; return;
} }
} }

View File

@ -13,6 +13,8 @@
// limitations under the License. // limitations under the License.
use std::convert::Into; use std::convert::Into;
use std::sync::Arc; use std::sync::Arc;
use std::thread::sleep;
use std::time::Duration;
use gflags; use gflags;
use metrics_exporter_prometheus; use metrics_exporter_prometheus;
@ -104,6 +106,11 @@ fn main() -> anyhow::Result<()> {
let mut parent = Nursery::new(); let mut parent = Nursery::new();
// First we start the render thread. // First we start the render thread.
{ {
let prom_maint_handle = prom_handle.clone();
let maint_thread = thread::Handle::new(move || {
sleep(Duration::from_secs(5));
prom_maint_handle.run_upkeep();
});
// Introduce a new scope for our Arc to clone before moving it into the thread. // Introduce a new scope for our Arc to clone before moving it into the thread.
// thread::Handle starts the thread immediately so the render thread will usually start first. // thread::Handle starts the thread immediately so the render thread will usually start first.
let render_thread = thread::Handle::new(move || { let render_thread = thread::Handle::new(move || {
@ -119,7 +126,7 @@ fn main() -> anyhow::Result<()> {
} }
}; };
info!( info!(
listenthost = LISTENHOST.flag, listenhost = LISTENHOST.flag,
"Listening for metrics request on" "Listening for metrics request on"
); );
loop { loop {
@ -127,6 +134,7 @@ fn main() -> anyhow::Result<()> {
match server.recv() { match server.recv() {
Ok(req) => { Ok(req) => {
let response = tiny_http::Response::from_data(prom_handle.render()) let response = tiny_http::Response::from_data(prom_handle.render())
.with_header(tiny_http::Header::from_bytes(&b"Content-Type"[..], &b"text/plain"[..]).unwrap())
.with_status_code(200); .with_status_code(200);
if let Err(e) = req.respond(response) { if let Err(e) = req.respond(response) {
error!(err = ?e, "Error responding to request"); error!(err = ?e, "Error responding to request");
@ -139,6 +147,7 @@ fn main() -> anyhow::Result<()> {
} }
}); });
parent.adopt(Box::new(render_thread)); parent.adopt(Box::new(render_thread));
parent.adopt(Box::new(maint_thread));
} }
{ {
icmp::schedule_echo_server(&ping_hosts, &mut parent); icmp::schedule_echo_server(&ping_hosts, &mut parent);

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
use gflags; use gflags;
use metrics::{gauge, increment_counter, Label}; use metrics::{counter, gauge, Label};
use std::convert::From; use std::convert::From;
use std::io; use std::io;
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
@ -83,6 +83,16 @@ fn make_count_labels(domain_name: &str, result: &str) -> Vec<Label> {
)] )]
pub fn start_listen_thread(domain_name: &str, s: SocketAddr) { pub fn start_listen_thread(domain_name: &str, s: SocketAddr) {
debug!("starting thread"); debug!("starting thread");
let stun_attempt_counter =
counter!("stun_attempt_counter", make_count_labels(domain_name, "ok"));
let stun_attempt_latency_ms = gauge!(
"stun_attempt_latency_ms",
vec![Label::new("domain", domain_name.to_owned())]
);
let stun_success = gauge!(
"stun_success",
vec![Label::new("domain", domain_name.to_owned())]
);
loop { loop {
let now = SystemTime::now(); let now = SystemTime::now();
info!("Attempting to connect"); info!("Attempting to connect");
@ -94,17 +104,10 @@ pub fn start_listen_thread(domain_name: &str, s: SocketAddr) {
millis = finish_time.duration_since(now).unwrap().as_millis(), millis = finish_time.duration_since(now).unwrap().as_millis(),
conn_type = "Stun connection", conn_type = "Stun connection",
); );
increment_counter!("stun_attempt_counter", make_count_labels(domain_name, "ok")); stun_attempt_counter.increment(1);
gauge!( stun_attempt_latency_ms
"stun_attempt_latency_ms", .set(finish_time.duration_since(now).unwrap().as_millis() as f64);
finish_time.duration_since(now).unwrap().as_millis() as f64, stun_success.set(1 as f64);
vec![Label::new("domain", domain_name.to_owned())]
);
gauge!(
"stun_success",
1 as f64,
vec![Label::new("domain", domain_name.to_owned())]
);
} }
Err(ConnectError::Timeout(finish_time)) => { Err(ConnectError::Timeout(finish_time)) => {
info!( info!(
@ -113,30 +116,16 @@ pub fn start_listen_thread(domain_name: &str, s: SocketAddr) {
millis = finish_time.duration_since(now).unwrap().as_millis(), millis = finish_time.duration_since(now).unwrap().as_millis(),
conn_type = "Stun connection", conn_type = "Stun connection",
); );
increment_counter!( stun_attempt_counter.increment(1);
"stun_attempt_counter", stun_success.set(0 as f64);
make_count_labels(domain_name, "timeout")
);
gauge!(
"stun_success",
0 as f64,
vec![Label::new("domain", domain_name.to_owned())]
);
} }
Err(ConnectError::Err(e)) => { Err(ConnectError::Err(e)) => {
error!( error!(
timeout=true, success=false, err = ?e, timeout=true, success=false, err = ?e,
conn_type="Stun connection", conn_type="Stun connection",
); );
increment_counter!( stun_attempt_counter.increment(1);
"stun_attempt_counter", stun_success.set(0 as f64);
make_count_labels(domain_name, "err")
);
gauge!(
"stun_success",
0 as f64,
vec![Label::new("domain", domain_name.to_owned())]
);
} }
Err(ConnectError::Incomplete) => { Err(ConnectError::Incomplete) => {
error!( error!(
@ -145,15 +134,8 @@ pub fn start_listen_thread(domain_name: &str, s: SocketAddr) {
err = "Incomplete", err = "Incomplete",
conn_type = "Stun connection", conn_type = "Stun connection",
); );
increment_counter!( stun_attempt_counter.increment(1);
"stun_attempt_counter", stun_success.set(0 as f64);
make_count_labels(domain_name, "incomplete")
);
gauge!(
"stun_success",
0 as f64,
vec![Label::new("domain", domain_name.to_owned())]
);
} }
} }