#!/usr/bin/env python3 from ctypes import CDLL from time import sleep from sys import argv, exit import os import logging separate_log = False log_file = './psi-monitor.log' period = 2 ############################################################################### def cgroup2_root(): """ """ with open('/proc/mounts') as f: for line in f: if ' cgroup2 ' in line: # if line.startswith('cgroup2 '): return line[7:].rpartition(' cgroup2 ')[0].strip() def mlockall(): MCL_CURRENT = 1 MCL_FUTURE = 2 MCL_ONFAULT = 4 libc = CDLL('libc.so.6', use_errno=True) result = libc.mlockall( MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT ) if result != 0: result = libc.mlockall( MCL_CURRENT | MCL_FUTURE ) if result != 0: pass else: pass else: pass def psi_file_mem_to_metrics(psi_path): with open(psi_path) as f: psi_list = f.readlines() # print(psi_list) some_list, full_list = psi_list[0].split(' '), psi_list[1].split(' ') # print(some_list, full_list) some_avg10 = some_list[1].split('=')[1] some_avg60 = some_list[2].split('=')[1] some_avg300 = some_list[3].split('=')[1] full_avg10 = full_list[1].split('=')[1] full_avg60 = full_list[2].split('=')[1] full_avg300 = full_list[3].split('=')[1] return (some_avg10, some_avg60, some_avg300, full_avg10, full_avg60, full_avg300) def psi_file_cpu_to_metrics(psi_path): with open(psi_path) as f: psi_list = f.readlines() # print(psi_list) some_list = psi_list[0].split(' ') # print(some_list, full_list) some_avg10 = some_list[1].split('=')[1] some_avg60 = some_list[2].split('=')[1] some_avg300 = some_list[3].split('=')[1] return (some_avg10, some_avg60, some_avg300) def log(*msg): """ """ print(*msg) if separate_log: logging.info(*msg) ############################################################################### if separate_log: logging.basicConfig( filename=log_file, level=logging.INFO, format="%(asctime)s: %(message)s") try: target = argv[1] log('Set target to {}'.format(argv[1])) except IndexError: log('Set target to SYSTEM_WIDE to monitor /proc/pressure') target = 'SYSTEM_WIDE' if target == 'SYSTEM_WIDE': cpu_file = "/proc/pressure/cpu" memory_file = "/proc/pressure/memory" io_file = "/proc/pressure/io" else: cpu_file = cgroup2_root() + target + "/cpu.pressure" memory_file = cgroup2_root() + target + "/memory.pressure" io_file = cgroup2_root() + target + "/io.pressure" mlockall() try: (c_some_avg10, c_some_avg60, c_some_avg300 ) = psi_file_cpu_to_metrics(cpu_file) (m_some_avg10, m_some_avg60, m_some_avg300, m_full_avg10, m_full_avg60, m_full_avg300 ) = psi_file_mem_to_metrics(memory_file) (i_some_avg10, i_some_avg60, i_some_avg300, i_full_avg10, i_full_avg60, i_full_avg300 ) = psi_file_mem_to_metrics(io_file) except Exception: log('Cannot open pressure files') log('Exit') exit() log('Starting psi-monitor, target: {}, period: {}'.format(target, period)) log('----------------------------------------------------------------------' '--------------------------------------------') log(' some cpu pressure || some memory pressure | full memory pressure ||' ' some io pressure | full io pressure') log('---------------------||----------------------|----------------------||' '----------------------|---------------------') log(' avg10 avg60 avg300 || avg10 avg60 avg300 | avg10 avg60 avg300 ||' ' avg10 avg60 avg300 | avg10 avg60 avg300') log('------ ------ ------ || ------ ------ ------ | ------ ------ ------ ||' ' ------ ------ ------ | ------ ------ ------') while True: (c_some_avg10, c_some_avg60, c_some_avg300 ) = psi_file_cpu_to_metrics(cpu_file) (m_some_avg10, m_some_avg60, m_some_avg300, m_full_avg10, m_full_avg60, m_full_avg300 ) = psi_file_mem_to_metrics(memory_file) (i_some_avg10, i_some_avg60, i_some_avg300, i_full_avg10, i_full_avg60, i_full_avg300 ) = psi_file_mem_to_metrics(io_file) log('{} {} {} || {} {} {} | {} {} {} || {} {} {} | {} {} {}'.format( c_some_avg10.rjust(6), c_some_avg60.rjust(6), c_some_avg300.rjust(6), m_some_avg10.rjust(6), m_some_avg60.rjust(6), m_some_avg300.rjust(6), m_full_avg10.rjust(6), m_full_avg60.rjust(6), m_full_avg300.rjust(6), i_some_avg10.rjust(6), i_some_avg60.rjust(6), i_some_avg300.rjust(6), i_full_avg10.rjust(6), i_full_avg60.rjust(6), i_full_avg300.rjust(6) )) try: sleep(period) except KeyboardInterrupt: log('Exit') exit()