@@ -41,6 +41,9 @@ use crate::{
4141mod guarded_channel;
4242mod path_state;
4343
44+ #[ cfg( feature = "metrics" ) ]
45+ mod metrics;
46+
4447// TODO: use this
4548// /// Number of addresses that are not active that we keep around per endpoint.
4649// ///
@@ -79,6 +82,9 @@ const APPLICATION_ABANDON_PATH: u8 = 30;
7982/// in a high frequency, and to keep data about previous path around for subsequent connections.
8083const ACTOR_MAX_IDLE_TIMEOUT : Duration = Duration :: from_secs ( 60 ) ;
8184
85+ /// Interval in which connection and path metrics are emitted.
86+ const METRICS_INTERVAL : Duration = Duration :: from_secs ( 10 ) ;
87+
8288/// A stream of events from all paths for all connections.
8389///
8490/// The connection is identified using [`ConnId`]. The event `Err` variant happens when the
@@ -224,6 +230,7 @@ impl RemoteStateActor {
224230 trace ! ( "actor started" ) ;
225231 let idle_timeout = MaybeFuture :: None ;
226232 tokio:: pin!( idle_timeout) ;
233+ let mut metrics_interval = time:: interval ( METRICS_INTERVAL ) ;
227234 loop {
228235 let scheduled_path_open = match self . scheduled_open_path {
229236 Some ( when) => MaybeFuture :: Some ( time:: sleep_until ( when) ) ,
@@ -266,6 +273,9 @@ impl RemoteStateActor {
266273 self . scheduled_holepunch = None ;
267274 self . trigger_holepunching( ) . await ;
268275 }
276+ _ = metrics_interval. tick( ) => {
277+ self . record_metrics( ) ;
278+ }
269279 _ = & mut idle_timeout => {
270280 if self . connections. is_empty( ) && inbox. close_if_idle( ) {
271281 trace!( "idle timeout expired and still idle: terminate actor" ) ;
@@ -388,7 +398,8 @@ impl RemoteStateActor {
388398 paths : Default :: default ( ) ,
389399 open_paths : Default :: default ( ) ,
390400 path_ids : Default :: default ( ) ,
391- transport_summary : TransportSummary :: default ( ) ,
401+ #[ cfg( feature = "metrics" ) ]
402+ metrics : Default :: default ( ) ,
392403 } )
393404 . into_mut ( ) ;
394405
@@ -575,8 +586,10 @@ impl RemoteStateActor {
575586
576587 fn handle_connection_close ( & mut self , conn_id : ConnId ) {
577588 if let Some ( state) = self . connections . remove ( & conn_id) {
578- self . metrics . num_conns_closed . inc ( ) ;
579- state. transport_summary . record ( & self . metrics ) ;
589+ #[ cfg( feature = "metrics" ) ]
590+ state. metrics . record_closed ( & self . metrics ) ;
591+ #[ cfg( not( feature = "metrics" ) ) ]
592+ let _ = state;
580593 }
581594 if self . connections . is_empty ( ) {
582595 trace ! ( "last connection closed - clearing selected_path" ) ;
@@ -1025,6 +1038,13 @@ impl RemoteStateActor {
10251038 }
10261039 }
10271040 }
1041+
1042+ fn record_metrics ( & mut self ) {
1043+ #[ cfg( feature = "metrics" ) ]
1044+ for state in self . connections . values_mut ( ) {
1045+ state. record_metrics_periodic ( & self . metrics , self . selected_path . get ( ) ) ;
1046+ }
1047+ }
10281048}
10291049
10301050/// Messages to send to the [`RemoteStateActor`].
@@ -1127,8 +1147,11 @@ struct ConnectionState {
11271147 open_paths : FxHashMap < PathId , transports:: Addr > ,
11281148 /// Reverse map of [`Self::paths].
11291149 path_ids : FxHashMap < transports:: Addr , PathId > ,
1130- /// Summary over transports used in this connection, for metrics tracking.
1131- transport_summary : TransportSummary ,
1150+ /// Tracker for stateful metrics for this connection and its paths
1151+ ///
1152+ /// Feature-gated on the `metrics` feature because it increases memory use.
1153+ #[ cfg( feature = "metrics" ) ]
1154+ metrics : self :: metrics:: MetricsTracker ,
11321155}
11331156
11341157impl ConnectionState {
@@ -1140,7 +1163,8 @@ impl ConnectionState {
11401163
11411164 /// Tracks an open path for the connection.
11421165 fn add_open_path ( & mut self , remote : transports:: Addr , path_id : PathId ) {
1143- self . transport_summary . add_path ( & remote) ;
1166+ #[ cfg( feature = "metrics" ) ]
1167+ self . metrics . add_path ( path_id, & remote) ;
11441168 self . paths . insert ( path_id, remote. clone ( ) ) ;
11451169 self . open_paths . insert ( path_id, remote. clone ( ) ) ;
11461170 self . path_ids . insert ( remote, path_id) ;
@@ -1153,11 +1177,15 @@ impl ConnectionState {
11531177 self . path_ids . remove ( & addr) ;
11541178 }
11551179 self . open_paths . remove ( path_id) ;
1180+ #[ cfg( feature = "metrics" ) ]
1181+ self . metrics . remove_path ( path_id) ;
11561182 }
11571183
11581184 /// Removes the path from the open paths.
11591185 fn remove_open_path ( & mut self , path_id : & PathId ) {
11601186 self . open_paths . remove ( path_id) ;
1187+ #[ cfg( feature = "metrics" ) ]
1188+ self . metrics . remove_path ( path_id) ;
11611189
11621190 self . update_pub_path_info ( ) ;
11631191 }
@@ -1177,6 +1205,19 @@ impl ConnectionState {
11771205
11781206 self . pub_open_paths . set ( new) . ok ( ) ;
11791207 }
1208+
1209+ #[ cfg( feature = "metrics" ) ]
1210+ fn record_metrics_periodic (
1211+ & mut self ,
1212+ metrics : & MagicsockMetrics ,
1213+ selected_path : Option < transports:: Addr > ,
1214+ ) {
1215+ let Some ( conn) = self . handle . upgrade ( ) else {
1216+ return ;
1217+ } ;
1218+ self . metrics
1219+ . record_periodic ( metrics, & conn, & self . open_paths , selected_path) ;
1220+ }
11801221}
11811222
11821223/// Watcher for the open paths and selected transmission path in a connection.
@@ -1387,41 +1428,3 @@ impl Future for OnClosed {
13871428 Poll :: Ready ( self . conn_id )
13881429 }
13891430}
1390-
1391- /// Used for metrics tracking.
1392- #[ derive( Debug , Clone , Copy , Default ) ]
1393- enum TransportSummary {
1394- #[ default]
1395- None ,
1396- IpOnly ,
1397- RelayOnly ,
1398- IpAndRelay ,
1399- }
1400-
1401- impl TransportSummary {
1402- fn add_path ( & mut self , addr : & transports:: Addr ) {
1403- use transports:: Addr ;
1404- * self = match ( * self , addr) {
1405- ( TransportSummary :: None | TransportSummary :: IpOnly , Addr :: Ip ( _) ) => Self :: IpOnly ,
1406- ( TransportSummary :: None | TransportSummary :: RelayOnly , Addr :: Relay ( _, _) ) => {
1407- Self :: RelayOnly
1408- }
1409- _ => Self :: IpAndRelay ,
1410- }
1411- }
1412-
1413- fn record ( & self , metrics : & MagicsockMetrics ) {
1414- match self {
1415- TransportSummary :: IpOnly => {
1416- metrics. num_conns_transport_ip_only . inc ( ) ;
1417- }
1418- TransportSummary :: RelayOnly => {
1419- metrics. num_conns_transport_relay_only . inc ( ) ;
1420- }
1421- TransportSummary :: IpAndRelay => {
1422- metrics. num_conns_transport_ip_and_relay . inc ( ) ;
1423- }
1424- TransportSummary :: None => { }
1425- }
1426- }
1427- }
0 commit comments