30 lines
1.1 KiB
Python
30 lines
1.1 KiB
Python
"""Sample interface counters without summing physical and virtual interfaces."""
|
|||
|
|
import re
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
|
||
|
|
class NetworkRates:
|
||
|
|
def __init__(self, root='/sys/class/net'):
|
||
|
|
self.root = Path(root)
|
||
|
|
self.previous = None
|
||
|
|
|
||
|
|
def sample(self, interface, now):
|
||
|
|
try:
|
||
|
|
if not re.fullmatch(r'[\w.:-]{1,64}', interface):
|
||
|
|
raise ValueError('invalid interface')
|
||
|
|
directory = self.root / interface / 'statistics'
|
||
|
|
rx = int((directory / 'rx_bytes').read_text())
|
||
|
|
tx = int((directory / 'tx_bytes').read_text())
|
||
|
|
if rx < 0 or tx < 0:
|
||
|
|
raise ValueError('negative counter')
|
||
|
|
except (OSError, ValueError, TypeError):
|
||
|
|
self.previous = None
|
||
|
|
return None, None
|
||
|
|
previous = self.previous
|
||
|
|
self.previous = interface, now, rx, tx
|
||
|
|
if previous is None or previous[0] != interface or now <= previous[1]:
|
||
|
|
return None, None
|
||
|
|
elapsed = now - previous[1]
|
||
|
|
return (None if rx < previous[2] else (rx - previous[2]) / elapsed,
|
||
|
|
None if tx < previous[3] else (tx - previous[3]) / elapsed)
|