improve psi-monitor

This commit is contained in:
Alexey Avramov 2019-09-09 00:14:42 +09:00
parent 2738b80ff7
commit e81fc9a824
2 changed files with 137 additions and 236 deletions

214
pm
View File

@ -1,214 +0,0 @@
#!/usr/bin/env python3
from ctypes import CDLL
from time import sleep
from sys import argv, exit
import os
import logging
"""
--target /system.slice
--period 2
--log-file ./psi.log
"""
separate_log = True
log_file = './psi-monitor.log'
period = 2
cpu_file = "./cpu"
memory_file = "./memory"
io_file = "./io"
"""
"""
#
try:
target = argv[1] # '.'
print('Set target to {}'.format(argv[1]))
except IndexError:
print('Set target to SYSTEM_WIDE to monitor /proc/pressure')
target = 'SYSTEM_WIDE'
# 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 = target + "/cpu.pressure"
memory_file = target + "/memory.pressure"
io_file = target + "/io.pressure"
###############################################################################
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)
###############################################################################
logging.basicConfig(
filename=log_file,
level=logging.INFO,
format="%(asctime)s: %(message)s")
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()
"""
if not os.path.exists('/proc/pressure'):
print('PSI path does not exist. 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()

View File

@ -2,8 +2,28 @@
from ctypes import CDLL from ctypes import CDLL
from time import sleep from time import sleep
from sys import argv from sys import argv, exit
import os 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(): def mlockall():
@ -28,13 +48,13 @@ def mlockall():
pass pass
def psi_path_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()
# print(psi_list) # print(psi_list)
some_list, full_list = psi_list[0].split(' '), psi_list[1].split(' ') some_list, full_list = psi_list[0].split(' '), psi_list[1].split(' ')
#print(some_list, full_list) # print(some_list, full_list)
some_avg10 = some_list[1].split('=')[1] some_avg10 = some_list[1].split('=')[1]
some_avg60 = some_list[2].split('=')[1] some_avg60 = some_list[2].split('=')[1]
some_avg300 = some_list[3].split('=')[1] some_avg300 = some_list[3].split('=')[1]
@ -47,31 +67,126 @@ def psi_path_to_metrics(psi_path):
full_avg10, full_avg60, full_avg300) full_avg10, full_avg60, full_avg300)
if len(argv) > 1: def psi_file_cpu_to_metrics(psi_path):
psi_path = argv[1]
else: with open(psi_path) as f:
psi_path = '/proc/pressure/memory' 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"
if not os.path.exists(psi_path):
print('PSI path does not exist. Exit.')
exit()
mlockall() mlockall()
print('Path to PSI file: {}\n'.format(psi_path)) 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('------ ------ ------ || ------ ------ ------ | ------ ------ ------ ||'
' ------ ------ ------ | ------ ------ ------')
print(' avg10 avg60 avg300 avg10 avg60 avg300')
while True: while True:
(some_avg10, some_avg60, some_avg300,
full_avg10, full_avg60, full_avg300) = psi_path_to_metrics(psi_path)
print('some {} {} {} | full {} {} {}'.format( (c_some_avg10, c_some_avg60, c_some_avg300
some_avg10.rjust(6), ) = psi_file_cpu_to_metrics(cpu_file)
some_avg60.rjust(6),
some_avg300.rjust(6),
full_avg10.rjust(6),
full_avg60.rjust(6),
full_avg300.rjust(6)))
sleep(2) (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()