1+ use std:: fs;
12use std:: time:: Duration ;
23
34use apollo_metrics:: metrics:: LossyIntoF64 ;
@@ -19,6 +20,52 @@ use crate::metrics::{
1920 SYSTEM_USED_MEMORY_BYTES ,
2021} ;
2122
23+ /// Reads TCP statistics from /proc/net/snmp on Linux systems
24+ /// Returns (segments_out, retransmitted_segments) if successful
25+ #[ allow( dead_code) ] // TODO(AndrewL): remove this once the function is used
26+ fn get_tcp_stats ( ) -> Option < ( u64 , u64 ) > {
27+ let content = match fs:: read_to_string ( "/proc/net/snmp" ) {
28+ Ok ( c) => c,
29+ Err ( e) => {
30+ warn ! ( "Failed to read /proc/net/snmp: {}" , e) ;
31+ return None ;
32+ }
33+ } ;
34+
35+ // Parse Tcp statistics
36+ // Format is two lines: Tcp: <keys>\nTcp: <values>
37+ let lines: Vec < & str > = content. lines ( ) . collect ( ) ;
38+ for i in 0 ..lines. len ( ) . saturating_sub ( 1 ) {
39+ if lines[ i] . starts_with ( "Tcp:" ) && lines[ i + 1 ] . starts_with ( "Tcp:" ) {
40+ let keys: Vec < & str > = lines[ i] . split_whitespace ( ) . skip ( 1 ) . collect ( ) ;
41+ let values: Vec < & str > = lines[ i + 1 ] . split_whitespace ( ) . skip ( 1 ) . collect ( ) ;
42+
43+ let mut out_segs = None ;
44+ let mut retrans_segs = None ;
45+
46+ for ( key, val) in keys. iter ( ) . zip ( values. iter ( ) ) {
47+ match * key {
48+ "OutSegs" => out_segs = val. parse ( ) . ok ( ) ,
49+ "RetransSegs" => retrans_segs = val. parse ( ) . ok ( ) ,
50+ _ => { }
51+ }
52+ }
53+
54+ if out_segs. is_none ( ) || retrans_segs. is_none ( ) {
55+ warn ! (
56+ "Could not find OutSegs or RetransSegs in /proc/net/snmp. Found keys: {:?}" ,
57+ keys
58+ ) ;
59+ }
60+
61+ return Some ( ( out_segs?, retrans_segs?) ) ;
62+ }
63+ }
64+
65+ warn ! ( "Could not find Tcp: section in /proc/net/snmp" ) ;
66+ None
67+ }
68+
2269/// Collects system-wide and process-specific metrics (CPU, memory)
2370fn collect_system_and_process_metrics ( system : & mut System , current_pid : Pid ) {
2471 system. refresh_all ( ) ;
0 commit comments