@@ -25,6 +25,50 @@ const NANOS_PER_SECOND: f64 = 1_000_000_000.0;
2525/// constant that has been 100 on all mainstream architectures for decades.
2626const CLOCK_TICKS_PER_SEC : u64 = 100 ;
2727
28+ /// Reads TCP statistics from /proc/net/snmp on Linux systems.
29+ /// Returns (segments_out, retransmitted_segments) if successful.
30+ #[ allow( dead_code) ] // TODO(AndrewL): remove this once the function is used
31+ fn get_tcp_stats ( ) -> Option < ( u64 , u64 ) > {
32+ let content = match fs:: read_to_string ( "/proc/net/snmp" ) {
33+ Ok ( c) => c,
34+ Err ( e) => {
35+ warn ! ( "Failed to read /proc/net/snmp: {}" , e) ;
36+ return None ;
37+ }
38+ } ;
39+
40+ let lines: Vec < & str > = content. lines ( ) . collect ( ) ;
41+ for i in 0 ..lines. len ( ) . saturating_sub ( 1 ) {
42+ if lines[ i] . starts_with ( "Tcp:" ) && lines[ i + 1 ] . starts_with ( "Tcp:" ) {
43+ let keys: Vec < & str > = lines[ i] . split_whitespace ( ) . skip ( 1 ) . collect ( ) ;
44+ let values: Vec < & str > = lines[ i + 1 ] . split_whitespace ( ) . skip ( 1 ) . collect ( ) ;
45+
46+ let mut out_segs = None ;
47+ let mut retrans_segs = None ;
48+
49+ for ( key, val) in keys. iter ( ) . zip ( values. iter ( ) ) {
50+ match * key {
51+ "OutSegs" => out_segs = val. parse ( ) . ok ( ) ,
52+ "RetransSegs" => retrans_segs = val. parse ( ) . ok ( ) ,
53+ _ => { }
54+ }
55+ }
56+
57+ if out_segs. is_none ( ) || retrans_segs. is_none ( ) {
58+ warn ! (
59+ "Could not find OutSegs or RetransSegs in /proc/net/snmp. Found keys: {:?}" ,
60+ keys
61+ ) ;
62+ }
63+
64+ return Some ( ( out_segs?, retrans_segs?) ) ;
65+ }
66+ }
67+
68+ warn ! ( "Could not find Tcp: section in /proc/net/snmp" ) ;
69+ None
70+ }
71+
2872/// Reads memory info, returning (total, available) in bytes.
2973///
3074/// Tries cgroup limits first (container-aware), falls back to /proc/meminfo.
0 commit comments