Fix psi-monitor

This commit is contained in:
Alexey Avramov 2019-09-21 00:54:22 +09:00
parent 82ea085e63
commit fe02067e42

View File

@ -1,16 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from ctypes import CDLL
from time import sleep
from sys import argv, exit
import os import os
import logging from time import sleep
from ctypes import CDLL
from argparse import ArgumentParser
separate_log = False
log_file = './psi-monitor.log'
period = 2
############################################################################### ###############################################################################
@ -18,14 +12,15 @@ period = 2
def cgroup2_root(): def cgroup2_root():
""" """
""" """
with open('/proc/mounts') as f: with open(mounts) as f:
for line in f: for line in f:
if ' cgroup2 ' in line: if cgroup2_separator in line:
# if line.startswith('cgroup2 '): return line.partition(cgroup2_separator)[0].partition(' ')[2]
return line[7:].rpartition(' cgroup2 ')[0].strip()
def mlockall(): def mlockall():
"""
"""
MCL_CURRENT = 1 MCL_CURRENT = 1
MCL_FUTURE = 2 MCL_FUTURE = 2
@ -49,6 +44,8 @@ def mlockall():
def psi_file_mem_to_metrics(psi_path): def psi_file_mem_to_metrics(psi_path):
"""
"""
with open(psi_path) as f: with open(psi_path) as f:
psi_list = f.readlines() psi_list = f.readlines()
@ -68,6 +65,8 @@ def psi_file_mem_to_metrics(psi_path):
def psi_file_cpu_to_metrics(psi_path): def psi_file_cpu_to_metrics(psi_path):
"""
"""
with open(psi_path) as f: with open(psi_path) as f:
psi_list = f.readlines() psi_list = f.readlines()
@ -93,49 +92,109 @@ def log(*msg):
############################################################################### ###############################################################################
parser = ArgumentParser()
parser.add_argument(
'-t',
'--target',
help="""target (cgroup2 or SYTSTEM_WIDE)""",
default='SYSTEM_WIDE',
type=str
)
parser.add_argument(
'-p',
'--period',
help="""period in sec""",
default=2,
type=float
)
parser.add_argument(
'-l',
'--log',
help="""path to log file""",
default=None,
type=str
)
args = parser.parse_args()
target = args.target
period = args.period
log_file = args.log
if log_file is None:
separate_log = False
else:
separate_log = True
import logging
def sleeeep():
try:
sleep(period)
except KeyboardInterrupt:
log('Exit')
exit()
###############################################################################
if separate_log: if separate_log:
logging.basicConfig( logging.basicConfig(
filename=log_file, filename=log_file,
level=logging.INFO, level=logging.INFO,
format="%(asctime)s: %(message)s") format="%(asctime)s: %(message)s")
###############################################################################
try:
target = argv[1] log('target: {}'.format(target))
log('Set target to {}'.format(argv[1])) log('period: {}'.format(period))
except IndexError: if log_file is not None:
log('Set target to SYSTEM_WIDE to monitor /proc/pressure') log('log file: {}'.format(log_file))
target = 'SYSTEM_WIDE'
if not os.path.exists('/proc/pressure'):
log('ERROR: /proc/pressure does not exist, PSI is not supported, exit')
exit()
if target == 'SYSTEM_WIDE': if target == 'SYSTEM_WIDE':
cpu_file = "/proc/pressure/cpu" cpu_file = "/proc/pressure/cpu"
memory_file = "/proc/pressure/memory" memory_file = "/proc/pressure/memory"
io_file = "/proc/pressure/io" io_file = "/proc/pressure/io"
else: else:
cpu_file = cgroup2_root() + target + "/cpu.pressure"
memory_file = cgroup2_root() + target + "/memory.pressure" mounts = '/proc/mounts'
io_file = cgroup2_root() + target + "/io.pressure" cgroup2_separator = ' cgroup2 rw,'
cgroup2_mountpoint = cgroup2_root()
if cgroup2_mountpoint is None:
log('ERROR: unified cgroup hierarchy is not mounted, exit')
exit()
else:
log('cgroup2 mountpoint: {}'.format(cgroup2_mountpoint))
cpu_file = cgroup2_mountpoint + target + "/cpu.pressure"
memory_file = cgroup2_mountpoint + target + "/memory.pressure"
io_file = cgroup2_mountpoint + target + "/io.pressure"
mlockall() 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('Starting psi-monitor, target: {}, period: {}'.format(target, period))
log('----------------------------------------------------------------------' log('----------------------------------------------------------------------'
@ -152,6 +211,22 @@ log('------ ------ ------ || ------ ------ ------ | ------ ------ ------ ||'
while True: while True:
if not os.path.exists(cpu_file):
log('ERROR: cpu pressure file does not exist: {}'.format(cpu_file))
sleeeep()
continue
if not os.path.exists(memory_file):
log('ERROR: memory pressure file does not exist: {}'.format(
memory_file))
sleeeep()
continue
if not os.path.exists(io_file):
log('ERROR: io pressure file does not exist: {}'.format(cpu_file))
sleeeep()
continue
(c_some_avg10, c_some_avg60, c_some_avg300 (c_some_avg10, c_some_avg60, c_some_avg300
) = psi_file_cpu_to_metrics(cpu_file) ) = psi_file_cpu_to_metrics(cpu_file)
@ -185,8 +260,4 @@ while True:
)) ))
try: sleeeep()
sleep(period)
except KeyboardInterrupt:
log('Exit')
exit()