iroh_proxy_utils/upstream/
metrics.rs1use std::{
2 collections::BTreeMap,
3 sync::{Arc, RwLock},
4};
5
6use iroh_metrics::Counter;
7
8use crate::Authority;
9
10#[derive(Debug, Default)]
15pub struct UpstreamMetrics {
16 targets: RwLock<BTreeMap<Authority, Arc<TargetMetrics>>>,
17 pub(super) connections_accepted: Counter,
18 pub(super) connections_completed: Counter,
19 pub(super) requests_accepted: Counter,
20 pub(super) requests_denied: Counter,
21 pub(super) requests_completed: Counter,
22 pub(super) requests_failed: Counter,
23}
24
25impl UpstreamMetrics {
26 pub fn denied_requests(&self) -> u64 {
28 self.requests_denied.get()
29 }
30
31 pub fn accepted_requests(&self) -> u64 {
33 self.requests_accepted.get()
34 }
35
36 pub fn active_requests(&self) -> u64 {
40 self.requests_accepted
41 .get()
42 .saturating_sub(self.requests_completed.get())
43 .saturating_sub(self.requests_failed.get())
44 }
45
46 pub fn active_iroh_connections(&self) -> u64 {
50 self.connections_accepted
51 .get()
52 .saturating_sub(self.connections_completed.get())
53 }
54
55 pub fn total_iroh_connections(&self) -> u64 {
57 self.connections_accepted.get()
58 }
59
60 pub fn get(&self, target: &Authority) -> Option<Arc<TargetMetrics>> {
62 let inner = self.targets.read().expect("poisoned");
63 inner.get(target).cloned()
64 }
65
66 pub(super) fn get_or_insert(&self, target: Authority) -> Arc<TargetMetrics> {
67 {
68 let inner = self.targets.read().expect("poisoned");
69 if let Some(value) = inner.get(&target) {
70 return value.clone();
71 }
72 }
73 let mut inner = self.targets.write().expect("poisoned");
74 let value = inner.entry(target).or_default();
75 value.clone()
76 }
77
78 pub fn for_each(&self, f: impl Fn(&Authority, &TargetMetrics)) {
82 let inner = self.targets.read().expect("poisoned");
83 for (k, v) in inner.iter() {
84 f(k, v);
85 }
86 }
87}
88
89#[derive(Default, Debug)]
95pub struct TargetMetrics {
96 pub(super) requests_accepted: Counter,
97 pub(super) requests_denied: Counter,
98 pub(super) requests_completed: Counter,
99 pub(super) requests_failed: Counter,
100 pub(super) bytes_to_origin: Counter,
101 pub(super) bytes_from_origin: Counter,
102}
103
104impl TargetMetrics {
105 pub fn denied_requests(&self) -> u64 {
107 self.requests_denied.get()
108 }
109
110 pub fn accepted_requests(&self) -> u64 {
112 self.requests_accepted.get()
113 }
114
115 pub fn failed_requests(&self) -> u64 {
117 self.requests_failed.get()
118 }
119
120 pub fn active_requests(&self) -> u64 {
124 self.requests_accepted
125 .get()
126 .saturating_sub(self.requests_completed.get())
127 .saturating_sub(self.requests_failed.get())
128 }
129
130 pub fn bytes_to_origin(&self) -> u64 {
132 self.bytes_to_origin.get()
133 }
134
135 pub fn bytes_from_origin(&self) -> u64 {
137 self.bytes_from_origin.get()
138 }
139}