use std::{
collections::BTreeMap,
sync::{Arc, RwLock},
};
use iroh_metrics::Counter;
use crate::Authority;
#[derive(Debug, Default)]
pub struct UpstreamMetrics {
targets: RwLock<BTreeMap<Authority, Arc<TargetMetrics>>>,
pub(super) connections_accepted: Counter,
pub(super) connections_completed: Counter,
pub(super) requests_accepted: Counter,
pub(super) requests_denied: Counter,
pub(super) requests_completed: Counter,
pub(super) requests_failed: Counter,
}
impl UpstreamMetrics {
pub fn denied_requests(&self) -> u64 {
self.requests_denied.get()
}
pub fn accepted_requests(&self) -> u64 {
self.requests_accepted.get()
}
pub fn active_requests(&self) -> u64 {
self.requests_accepted
.get()
.saturating_sub(self.requests_completed.get())
.saturating_sub(self.requests_failed.get())
}
pub fn active_iroh_connections(&self) -> u64 {
self.connections_accepted
.get()
.saturating_sub(self.connections_completed.get())
}
pub fn total_iroh_connections(&self) -> u64 {
self.connections_accepted.get()
}
pub fn get(&self, target: &Authority) -> Option<Arc<TargetMetrics>> {
let inner = self.targets.read().expect("poisoned");
inner.get(target).cloned()
}
pub(super) fn get_or_insert(&self, target: Authority) -> Arc<TargetMetrics> {
{
let inner = self.targets.read().expect("poisoned");
if let Some(value) = inner.get(&target) {
return value.clone();
}
}
let mut inner = self.targets.write().expect("poisoned");
let value = inner.entry(target).or_default();
value.clone()
}
pub fn for_each(&self, f: impl Fn(&Authority, &TargetMetrics)) {
let inner = self.targets.read().expect("poisoned");
for (k, v) in inner.iter() {
f(k, v);
}
}
}
#[derive(Default, Debug)]
pub struct TargetMetrics {
pub(super) requests_accepted: Counter,
pub(super) requests_denied: Counter,
pub(super) requests_completed: Counter,
pub(super) requests_failed: Counter,
pub(super) bytes_to_origin: Counter,
pub(super) bytes_from_origin: Counter,
}
impl TargetMetrics {
pub fn denied_requests(&self) -> u64 {
self.requests_denied.get()
}
pub fn accepted_requests(&self) -> u64 {
self.requests_accepted.get()
}
pub fn failed_requests(&self) -> u64 {
self.requests_failed.get()
}
pub fn active_requests(&self) -> u64 {
self.requests_accepted
.get()
.saturating_sub(self.requests_completed.get())
.saturating_sub(self.requests_failed.get())
}
pub fn bytes_to_origin(&self) -> u64 {
self.bytes_to_origin.get()
}
pub fn bytes_from_origin(&self) -> u64 {
self.bytes_from_origin.get()
}
}