Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package s-tui for openSUSE:Factory checked in at 2021-03-03 18:35:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/s-tui (Old) and /work/SRC/openSUSE:Factory/.s-tui.new.2378 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "s-tui" Wed Mar 3 18:35:56 2021 rev:6 rq:876539 version:1.1.1 Changes: -------- --- /work/SRC/openSUSE:Factory/s-tui/s-tui.changes 2020-07-17 20:52:44.637038820 +0200 +++ /work/SRC/openSUSE:Factory/.s-tui.new.2378/s-tui.changes 2021-03-03 18:36:08.147425394 +0100 @@ -1,0 +2,8 @@ +Sun Feb 28 16:22:50 UTC 2021 - Martin Hauke <[email protected]> + +- Update to version 1.1.1 + Bug fixes and stability + * Wrong reporting of duplicated values in CSV. + * Error messages printed to screen. + +------------------------------------------------------------------- Old: ---- s-tui-1.0.2.tar.gz New: ---- s-tui-1.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ s-tui.spec ++++++ --- /var/tmp/diff_new_pack.WSlE8x/_old 2021-03-03 18:36:08.595425716 +0100 +++ /var/tmp/diff_new_pack.WSlE8x/_new 2021-03-03 18:36:08.599425719 +0100 @@ -1,7 +1,7 @@ # # spec file for package s-tui # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # Copyright (c) 2019 Malcolm J Lewis <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -18,7 +18,7 @@ Name: s-tui -Version: 1.0.2 +Version: 1.1.1 Release: 0 Summary: Terminal based CPU stress and monitoring utility License: GPL-2.0-or-later ++++++ s-tui-1.0.2.tar.gz -> s-tui-1.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s-tui-1.0.2/README.md new/s-tui-1.1.1/README.md --- old/s-tui-1.0.2/README.md 2020-07-11 15:57:58.000000000 +0200 +++ new/s-tui-1.1.1/README.md 2021-02-27 11:15:49.000000000 +0100 @@ -234,6 +234,7 @@ s-tui uses [urwid](https://github.com/urwid/urwid) as a graphical engine. urwid only works with UNIX-like systems - Power read is supported on Intel Core CPUs of the second generation and newer (Sandy Bridge) + and on AMD Family 17h CPUs through the [amd_energy](https://www.kernel.org/doc/html/latest/hwmon/amd_energy.html) driver. - s-tui tested to run on Raspberry-Pi 4,3,2,1 ## FAQ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s-tui-1.0.2/s_tui/helper_functions.py new/s-tui-1.1.1/s_tui/helper_functions.py --- old/s-tui-1.0.2/s_tui/helper_functions.py 2020-07-11 15:57:58.000000000 +0200 +++ new/s-tui-1.1.1/s_tui/helper_functions.py 2021-02-27 11:15:49.000000000 +0100 @@ -30,7 +30,7 @@ from collections import OrderedDict -__version__ = "1.0.2" +__version__ = "1.1.1" _DEFAULT = object() PY3 = sys.version_info[0] == 3 @@ -93,7 +93,11 @@ csv_dict.update({'Time': time.strftime("%Y-%m-%d_%H:%M:%S")}) summaries = [val for key, val in sources.items()] for summarie in summaries: - csv_dict.update(summarie.source.get_sensors_summary()) + update_dict = dict() + for prob, val in summarie.source.get_sensors_summary().items(): + prob = summarie.source.get_source_name() + ":" + prob + update_dict[prob] = val + csv_dict.update(update_dict) fieldnames = [key for key, val in csv_dict.items()] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s-tui-1.0.2/s_tui/s_tui.py new/s-tui-1.1.1/s_tui/s_tui.py --- old/s-tui-1.0.2/s_tui/s_tui.py 2020-07-11 15:57:58.000000000 +0200 +++ new/s-tui-1.1.1/s_tui/s_tui.py 2021-02-27 11:15:49.000000000 +0100 @@ -36,6 +36,7 @@ import psutil import urwid +import urwid.curses_display try: import configparser @@ -748,7 +749,9 @@ def main(self): """ Starts the main loop and graph animation """ loop = MainLoop(self.view, DEFAULT_PALETTE, - handle_mouse=self.handle_mouse) + handle_mouse=self.handle_mouse, + # screen=urwid.curses_display.Screen() + ) self.view.show_graphs() self.animate_graph(loop) try: @@ -887,6 +890,12 @@ file_handler.setFormatter(log_formatter) root_logger.addHandler(file_handler) root_logger.setLevel(level) + else: + level = logging.ERROR + log_formatter = logging.Formatter( + "%(asctime)s [%(funcName)s()] [%(levelname)-5.5s] %(message)s") + root_logger = logging.getLogger() + root_logger.setLevel(level) if args.terminal or args.json: logging.info("Printing single line to terminal") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s-tui-1.0.2/s_tui/sources/rapl_power_source.py new/s-tui-1.1.1/s_tui/sources/rapl_power_source.py --- old/s-tui-1.0.2/s_tui/sources/rapl_power_source.py 2020-07-11 15:57:58.000000000 +0200 +++ new/s-tui-1.1.1/s_tui/sources/rapl_power_source.py 2021-02-27 11:15:49.000000000 +0100 @@ -25,7 +25,7 @@ import logging from s_tui.sources.source import Source -from s_tui.sources.rapl_read import rapl_read +from s_tui.sources.rapl_read import get_power_reader LOGGER = logging.getLogger(__name__) @@ -42,12 +42,14 @@ self.pallet = ('power light', 'power dark', 'power light smooth', 'power dark smooth') - self.last_probe_time = time.time() - self.last_probe = rapl_read() - if not self.last_probe: + self.reader = get_power_reader() + if not self.reader: self.is_available = False logging.debug("Power reading is not available") return + + self.last_probe_time = time.time() + self.last_probe = self.reader.read_power() self.max_power = 1 self.last_measurement = [0] * len(self.last_probe) @@ -62,7 +64,7 @@ def update(self): if not self.is_available: return - current_measurement_value = rapl_read() + current_measurement_value = self.reader.read_power() current_measurement_time = time.time() for m_idx, _ in enumerate(self.last_probe): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/s-tui-1.0.2/s_tui/sources/rapl_read.py new/s-tui-1.1.1/s_tui/sources/rapl_read.py --- old/s-tui-1.0.2/s_tui/sources/rapl_read.py 2020-07-11 15:57:58.000000000 +0200 +++ new/s-tui-1.1.1/s_tui/sources/rapl_read.py 2021-02-27 11:15:49.000000000 +0100 @@ -22,37 +22,90 @@ import logging import glob import os +import re from collections import namedtuple from s_tui.helper_functions import cat INTER_RAPL_DIR = '/sys/class/powercap/intel-rapl/' +AMD_ENERGY_DIR_GLOB = '/sys/devices/platform/amd_energy.0/hwmon/hwmon*/' MICRO_JOULE_IN_JOULE = 1000000.0 RaplStats = namedtuple('rapl', ['label', 'current', 'max']) -def rapl_read(): - """ Read power stats and return dictionary""" - basenames = glob.glob('/sys/class/powercap/intel-rapl:*/') - basenames = sorted(set({x for x in basenames})) - - pjoin = os.path.join - ret = list() - for path in basenames: - name = None - try: - name = cat(pjoin(path, 'name'), fallback=None, binary=False) - except (IOError, OSError, ValueError) as err: - logging.warning("ignoring %r for file %r", - (err, path), RuntimeWarning) - continue - if name: +class RaplReader: + def __init__(self): + basenames = glob.glob('/sys/class/powercap/intel-rapl:*/') + self.basenames = sorted(set({x for x in basenames})) + + def read_power(self): + """ Read power stats and return dictionary""" + + pjoin = os.path.join + ret = list() + for path in self.basenames: + name = None try: - current = cat(pjoin(path, 'energy_uj')) - max_reading = 0.0 - ret.append(RaplStats(name, float(current), max_reading)) + name = cat(pjoin(path, 'name'), fallback=None, binary=False) except (IOError, OSError, ValueError) as err: logging.warning("ignoring %r for file %r", (err, path), RuntimeWarning) - return ret + continue + if name: + try: + current = cat(pjoin(path, 'energy_uj')) + max_reading = 0.0 + ret.append(RaplStats(name, float(current), max_reading)) + except (IOError, OSError, ValueError) as err: + logging.warning("ignoring %r for file %r", + (err, path), RuntimeWarning) + return ret + + @staticmethod + def available(): + return os.path.exists("/sys/class/powercap/intel-rapl") + + +class AMDEnergyReader: + def __init__(self): + self.inputs = list(zip((cat(filename, binary=False) for filename in + sorted(glob.glob(AMD_ENERGY_DIR_GLOB + + 'energy*_label'))), + sorted(glob.glob(AMD_ENERGY_DIR_GLOB + + 'energy*_input')))) + + # How many socket does the system have? + socket_number = sum(1 for label, _ in self.inputs if 'socket' in label) + self.inputs.sort( + key=lambda x: self.get_input_position(x[0], socket_number)) + + @staticmethod + def match_label(label): + return re.search(r'E(core|socket)([0-9]+)', label) + + @staticmethod + def get_input_position(label, socket_number): + num = int(AMDEnergyReader.match_label(label).group(2)) + if 'socket' in label: + return num + else: + return num + socket_number + + def read_power(self): + ret = [] + for label, inp in self.inputs: + value = cat(inp) + ret.append(RaplStats(label, float(value), 0.0)) + return ret + + @staticmethod + def available(): + return os.path.exists("/sys/devices/platform/amd_energy.0") + + +def get_power_reader(): + for ReaderType in (RaplReader, AMDEnergyReader): + if ReaderType.available(): + return ReaderType() + return None
