proc_stats: report network stats for all interfaces
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
parent
8f8d780c72
commit
c684b063b2
|
@ -30,6 +30,7 @@ if TYPE_CHECKING:
|
||||||
|
|
||||||
VC_GEN_CMD_FILE = "/usr/bin/vcgencmd"
|
VC_GEN_CMD_FILE = "/usr/bin/vcgencmd"
|
||||||
STATM_FILE_PATH = "/proc/self/smaps_rollup"
|
STATM_FILE_PATH = "/proc/self/smaps_rollup"
|
||||||
|
NET_DEV_PATH = "/proc/net/dev"
|
||||||
TEMPERATURE_PATH = "/sys/class/thermal/thermal_zone0/temp"
|
TEMPERATURE_PATH = "/sys/class/thermal/thermal_zone0/temp"
|
||||||
STAT_UPDATE_TIME_MS = 1000
|
STAT_UPDATE_TIME_MS = 1000
|
||||||
REPORT_QUEUE_SIZE = 30
|
REPORT_QUEUE_SIZE = 30
|
||||||
|
@ -68,6 +69,7 @@ class ProcStats:
|
||||||
"disabled")
|
"disabled")
|
||||||
self.temp_file = pathlib.Path(TEMPERATURE_PATH)
|
self.temp_file = pathlib.Path(TEMPERATURE_PATH)
|
||||||
self.smaps = pathlib.Path(STATM_FILE_PATH)
|
self.smaps = pathlib.Path(STATM_FILE_PATH)
|
||||||
|
self.netdev_file = pathlib.Path(NET_DEV_PATH)
|
||||||
self.server.register_endpoint(
|
self.server.register_endpoint(
|
||||||
"/machine/proc_stats", ["GET"], self._handle_stat_request)
|
"/machine/proc_stats", ["GET"], self._handle_stat_request)
|
||||||
self.server.register_event_handler(
|
self.server.register_event_handler(
|
||||||
|
@ -80,6 +82,7 @@ class ProcStats:
|
||||||
self.total_throttled: int = 0
|
self.total_throttled: int = 0
|
||||||
self.last_throttled: int = 0
|
self.last_throttled: int = 0
|
||||||
self.update_sequence: int = 0
|
self.update_sequence: int = 0
|
||||||
|
self.last_net_stats: Dict[str, Dict[str, Any]] = {}
|
||||||
self.stat_update_cb.start()
|
self.stat_update_cb.start()
|
||||||
self.watchdog.start()
|
self.watchdog.start()
|
||||||
|
|
||||||
|
@ -94,7 +97,8 @@ class ProcStats:
|
||||||
return {
|
return {
|
||||||
'moonraker_stats': list(self.proc_stat_queue),
|
'moonraker_stats': list(self.proc_stat_queue),
|
||||||
'throttled_state': ts,
|
'throttled_state': ts,
|
||||||
'cpu_temp': cpu_temp
|
'cpu_temp': cpu_temp,
|
||||||
|
'network': self.last_net_stats
|
||||||
}
|
}
|
||||||
|
|
||||||
async def _handle_shutdown(self) -> None:
|
async def _handle_shutdown(self) -> None:
|
||||||
|
@ -114,18 +118,29 @@ class ProcStats:
|
||||||
proc_time = time.process_time()
|
proc_time = time.process_time()
|
||||||
time_diff = update_time - self.last_update_time
|
time_diff = update_time - self.last_update_time
|
||||||
usage = round((proc_time - self.last_proc_time) / time_diff * 100, 2)
|
usage = round((proc_time - self.last_proc_time) / time_diff * 100, 2)
|
||||||
cpu_temp, mem, mem_units = await self.event_loop.run_in_thread(
|
cpu_temp, mem, mem_units, net = await self.event_loop.run_in_thread(
|
||||||
self._read_system_files)
|
self._read_system_files)
|
||||||
|
for dev in net:
|
||||||
|
bytes_sec = 0.
|
||||||
|
if dev in self.last_net_stats:
|
||||||
|
last_dev_stats = self.last_net_stats[dev]
|
||||||
|
cur_total: int = net[dev]['rx_bytes'] + net[dev]['tx_bytes']
|
||||||
|
last_total: int = last_dev_stats['rx_bytes'] + \
|
||||||
|
last_dev_stats['tx_bytes']
|
||||||
|
bytes_sec = round((cur_total - last_total) / time_diff, 2)
|
||||||
|
net[dev]['bandwidth'] = bytes_sec
|
||||||
|
self.last_net_stats = net
|
||||||
result = {
|
result = {
|
||||||
"time": update_time,
|
'time': update_time,
|
||||||
"cpu_usage": usage,
|
'cpu_usage': usage,
|
||||||
"memory": mem,
|
'memory': mem,
|
||||||
"mem_units": mem_units,
|
'mem_units': mem_units
|
||||||
}
|
}
|
||||||
self.proc_stat_queue.append(result)
|
self.proc_stat_queue.append(result)
|
||||||
self.server.send_event("proc_stats:proc_stat_update", {
|
self.server.send_event("proc_stats:proc_stat_update", {
|
||||||
'moonraker_stats': result,
|
'moonraker_stats': result,
|
||||||
'cpu_temp': cpu_temp
|
'cpu_temp': cpu_temp,
|
||||||
|
'network': net
|
||||||
})
|
})
|
||||||
self.last_update_time = update_time
|
self.last_update_time = update_time
|
||||||
self.last_proc_time = proc_time
|
self.last_proc_time = proc_time
|
||||||
|
@ -161,7 +176,8 @@ class ProcStats:
|
||||||
def _read_system_files(self) -> Tuple:
|
def _read_system_files(self) -> Tuple:
|
||||||
mem, units = self._get_memory_usage()
|
mem, units = self._get_memory_usage()
|
||||||
temp = self._get_cpu_temperature()
|
temp = self._get_cpu_temperature()
|
||||||
return temp, mem, units
|
net_stats = self._get_net_stats()
|
||||||
|
return temp, mem, units, net_stats
|
||||||
|
|
||||||
def _get_memory_usage(self) -> Tuple[Optional[int], Optional[str]]:
|
def _get_memory_usage(self) -> Tuple[Optional[int], Optional[str]]:
|
||||||
try:
|
try:
|
||||||
|
@ -185,6 +201,24 @@ class ProcStats:
|
||||||
return None
|
return None
|
||||||
return temp
|
return temp
|
||||||
|
|
||||||
|
def _get_net_stats(self) -> Dict[str, Any]:
|
||||||
|
if self.netdev_file.exists():
|
||||||
|
net_stats: Dict[str, Any] = {}
|
||||||
|
try:
|
||||||
|
ret = self.netdev_file.read_text()
|
||||||
|
dev_info = re.findall(r"([\w]+):(.+)", ret)
|
||||||
|
for (dev_name, stats) in dev_info:
|
||||||
|
parsed_stats = stats.strip().split()
|
||||||
|
net_stats[dev_name] = {
|
||||||
|
'rx_bytes': int(parsed_stats[0]),
|
||||||
|
'tx_bytes': int(parsed_stats[8])
|
||||||
|
}
|
||||||
|
return net_stats
|
||||||
|
except Exception:
|
||||||
|
return {}
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
def _format_stats(self, stats: Dict[str, Any]) -> str:
|
def _format_stats(self, stats: Dict[str, Any]) -> str:
|
||||||
return f"System Time: {stats['time']:2f}, " \
|
return f"System Time: {stats['time']:2f}, " \
|
||||||
f"Usage: {stats['cpu_usage']}%, " \
|
f"Usage: {stats['cpu_usage']}%, " \
|
||||||
|
|
Loading…
Reference in New Issue