statistics: Export the OS and process load in a get_status() method

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2021-04-09 20:27:38 -04:00
parent cacf1197b6
commit 49a2b0354f
2 changed files with 48 additions and 17 deletions

View File

@ -307,6 +307,9 @@ The following are common printer attributes:
between micro-controller architectures and with each code revision. between micro-controller architectures and with each code revision.
- `printer.mcu.last_stats.<statistics_name>`: Statistics information - `printer.mcu.last_stats.<statistics_name>`: Statistics information
on the micro-controller connection. on the micro-controller connection.
- `printer.system_stats.sysload`, `printer.system_stats.cputime`,
`printer.system_stats.memavail`: Information on the host operating
system and process load.
The above list is subject to change - if using an attribute be sure to The above list is subject to change - if using an attribute be sure to
review the [Config Changes document](Config_Changes.md) when upgrading review the [Config Changes document](Config_Changes.md) when upgrading

View File

@ -1,25 +1,53 @@
# Support for logging periodic statistics # Support for logging periodic statistics
# #
# Copyright (C) 2018-2020 Kevin O'Connor <kevin@koconnor.net> # Copyright (C) 2018-2021 Kevin O'Connor <kevin@koconnor.net>
# #
# This file may be distributed under the terms of the GNU GPLv3 license. # This file may be distributed under the terms of the GNU GPLv3 license.
import os, time, logging import os, time, logging
def get_os_stats(eventtime): class PrinterSysStats:
# Get core usage stats def __init__(self, config):
msg = "sysload=%.2f cputime=%.3f" % (os.getloadavg()[0], time.clock()) printer = config.get_printer()
# Get available system memory self.last_process_time = self.total_process_time = 0.
self.last_load_avg = 0.
self.last_mem_avail = 0
self.mem_file = None
try: try:
f = open("/proc/meminfo", "rb") self.mem_file = open("/proc/meminfo", "rb")
data = f.read() except:
f.close() pass
printer.register_event_handler("klippy:disconnect", self._disconnect)
def _disconnect(self):
if self.mem_file is not None:
self.mem_file.close()
self.mem_file = None
def stats(self, eventtime):
# Get core usage stats
ptime = time.clock()
pdiff = ptime - self.last_process_time
self.last_process_time = ptime
if pdiff > 0.:
self.total_process_time += pdiff
self.last_load_avg = os.getloadavg()[0]
msg = "sysload=%.2f cputime=%.3f" % (self.last_load_avg,
self.total_process_time)
# Get available system memory
if self.mem_file is not None:
try:
self.mem_file.seek(0)
data = self.mem_file.read()
for line in data.split('\n'): for line in data.split('\n'):
if line.startswith("MemAvailable:"): if line.startswith("MemAvailable:"):
msg = "%s memavail=%s" % (msg, line.split()[1]) self.last_mem_avail = int(line.split()[1])
msg = "%s memavail=%d" % (msg, self.last_mem_avail)
break break
except: except:
pass pass
return (False, msg) return (False, msg)
def get_status(self, eventtime):
return {'sysload': self.last_load_avg,
'cputime': self.total_process_time,
'memavail': self.last_mem_avail}
class PrinterStats: class PrinterStats:
def __init__(self, config): def __init__(self, config):
@ -37,10 +65,10 @@ class PrinterStats:
def generate_stats(self, eventtime): def generate_stats(self, eventtime):
stats = [cb(eventtime) for cb in self.stats_cb] stats = [cb(eventtime) for cb in self.stats_cb]
if max([s[0] for s in stats]): if max([s[0] for s in stats]):
stats.append(get_os_stats(eventtime))
logging.info("Stats %.1f: %s", eventtime, logging.info("Stats %.1f: %s", eventtime,
' '.join([s[1] for s in stats])) ' '.join([s[1] for s in stats]))
return eventtime + 1. return eventtime + 1.
def load_config(config): def load_config(config):
config.get_printer().add_object('system_stats', PrinterSysStats(config))
return PrinterStats(config) return PrinterStats(config)