2022-07-09 07:57:49 +00:00
use std ::fs ::File ;
use std ::io ;
use std ::io ::prelude ::* ;
2022-07-09 08:33:19 +00:00
pub struct NetInfo {
dev_name : String ,
down : u64 ,
prev_down : u64 ,
up : u64 ,
prev_up : u64 ,
}
impl NetInfo {
pub fn new ( dev_name : String ) -> Self {
Self {
dev_name ,
down : 0 ,
prev_down : 0 ,
up : 0 ,
prev_up : 0 ,
}
}
pub fn update ( & mut self ) -> io ::Result < ( ) > {
let mut netdev_string = String ::new ( ) ;
{
let mut netdev_file : File = File ::open ( " /proc/net/dev " ) ? ;
netdev_file . read_to_string ( & mut netdev_string ) ? ;
}
let mut dev_line : Option < String > = None ;
for line in netdev_string . lines ( ) {
if line . starts_with ( & self . dev_name ) {
dev_line = Some ( line . to_owned ( ) ) ;
break ;
}
}
if let Some ( line ) = dev_line {
let entries : Vec < & str > = line . split_whitespace ( ) . collect ( ) ;
if entries . len ( ) < 10 {
return Err ( io ::Error ::new ( io ::ErrorKind ::Other , format! ( " NetInfo::update: Failed to parse /proc/net/dev, \" {} \" device line is too short " , self . dev_name ) ) ) ;
}
self . down = entries [ 1 ] . parse ( ) . map_err ( | _ | io ::Error ::new ( io ::ErrorKind ::Other , format! ( " NetInfo::update: Failed to parse recv bytes in /proc/net/dev for device \" {} \" " , self . dev_name ) ) ) ? ;
self . up = entries [ 9 ] . parse ( ) . map_err ( | _ | io ::Error ::new ( io ::ErrorKind ::Other , format! ( " NetInfo::update: Failed to parse recv bytes in /proc/net/dev for device \" {} \" " , self . dev_name ) ) ) ? ;
} else {
return Err ( io ::Error ::new (
io ::ErrorKind ::Other ,
format! (
" NetInfo::update: Failed to parse /proc/net/dev, can't find net device \" {} \" " ,
self . dev_name
) ,
) ) ;
}
Ok ( ( ) )
}
pub fn get_netstring ( & mut self ) -> String {
2022-07-09 09:35:54 +00:00
let down_diff : f64 = ( self . down - self . prev_down ) as f64 ;
2022-07-09 08:33:19 +00:00
self . prev_down = self . down ;
2022-07-09 09:35:54 +00:00
let up_diff : f64 = ( self . up - self . prev_up ) as f64 ;
2022-07-09 08:33:19 +00:00
self . prev_up = self . up ;
let mut output = String ::new ( ) ;
2022-07-09 09:35:54 +00:00
if down_diff > 1024.0 * 1024.0 {
output . push_str ( & format! ( " {:.2} MiB " , down_diff / ( 1024.0 * 1024.0 ) ) ) ;
} else if down_diff > 1024.0 {
output . push_str ( & format! ( " {:.2} KiB " , down_diff / 1024.0 ) ) ;
2022-07-09 08:33:19 +00:00
} else {
2022-07-09 09:35:54 +00:00
output . push_str ( & format! ( " {:.0} B " , down_diff ) ) ;
2022-07-09 08:33:19 +00:00
}
2022-07-09 09:35:54 +00:00
if up_diff > 1024.0 * 1024.0 {
output . push_str ( & format! ( " {:.2} MiB " , up_diff / ( 1024.0 * 1024.0 ) ) ) ;
} else if up_diff > 1024.0 {
output . push_str ( & format! ( " {:.2} KiB " , up_diff / 1024.0 ) ) ;
2022-07-09 08:33:19 +00:00
} else {
2022-07-09 09:35:54 +00:00
output . push_str ( & format! ( " {:.0} B " , up_diff ) ) ;
2022-07-09 08:33:19 +00:00
}
output
}
}
2022-07-09 07:57:49 +00:00
pub fn get_meminfo ( ) -> io ::Result < String > {
let mut meminfo_string = String ::new ( ) ;
{
let mut meminfo : File = File ::open ( " /proc/meminfo " ) ? ;
meminfo . read_to_string ( & mut meminfo_string ) ? ;
}
2022-07-09 09:21:28 +00:00
let mut is_total_mega = false ;
2022-07-09 07:57:49 +00:00
let mut total : u32 = 0 ;
let mut available : u32 = 0 ;
for line in meminfo_string . lines ( ) {
if line . starts_with ( " MemTotal: " ) {
let line_parts = line
. split_whitespace ( )
. map ( | s | s . to_owned ( ) )
. collect ::< Vec < String > > ( ) ;
total = line_parts [ 1 ]
. parse ( )
. map_err ( | _ | io ::Error ::new ( io ::ErrorKind ::Other , " MemTotal: parse error " ) ) ? ;
} else if line . starts_with ( " MemAvailable: " ) {
let line_parts = line
. split_whitespace ( )
. map ( | s | s . to_owned ( ) )
. collect ::< Vec < String > > ( ) ;
available = line_parts [ 1 ]
. parse ( )
. map_err ( | _ | io ::Error ::new ( io ::ErrorKind ::Other , " MemAvailable: parse error " ) ) ? ;
}
}
let mut used = total - available ;
2022-07-09 09:21:28 +00:00
let mut is_used_mega = false ;
2022-07-09 07:57:49 +00:00
if total = = 0 {
Ok ( " 0 " . into ( ) )
} else {
if total > 1024 {
total / = 1024 ;
2022-07-09 09:21:28 +00:00
is_total_mega = true ;
2022-07-09 07:57:49 +00:00
}
if used > 1024 {
used / = 1024 ;
2022-07-09 09:21:28 +00:00
is_used_mega = true ;
2022-07-09 07:57:49 +00:00
}
let mut output = format! ( " {} " , used ) ;
2022-07-09 09:21:28 +00:00
if is_used_mega {
output . push_str ( " MiB / " ) ;
2022-07-09 07:57:49 +00:00
} else {
output . push_str ( " KiB / " ) ;
}
output . push_str ( & format! ( " {} " , total ) ) ;
2022-07-09 09:21:28 +00:00
if is_total_mega {
output . push_str ( " MiB " ) ;
2022-07-09 07:57:49 +00:00
} else {
output . push_str ( " KiB " ) ;
}
Ok ( output )
}
}
2022-07-09 08:04:49 +00:00
pub fn get_loadavg ( ) -> io ::Result < String > {
let mut loadavg_string = String ::new ( ) ;
{
let mut loadavg_file : File = File ::open ( " /proc/loadavg " ) ? ;
loadavg_file . read_to_string ( & mut loadavg_string ) ? ;
}
let loadavg_parts : Vec < & str > = loadavg_string . split_whitespace ( ) . collect ( ) ;
if loadavg_parts . len ( ) < 3 {
return Err ( io ::Error ::new (
io ::ErrorKind ::Other ,
" loadavg: failed to parse " ,
) ) ;
}
Ok ( format! (
" {} {} {} " ,
loadavg_parts [ 0 ] , loadavg_parts [ 1 ] , loadavg_parts [ 2 ]
) )
}