138 lines
3.4 KiB
Python
Executable File
138 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
sort processes by oom_score
|
|
"""
|
|
from operator import itemgetter
|
|
from os import listdir
|
|
from argparse import ArgumentParser
|
|
'''
|
|
oom-sort -n 9
|
|
oom-sort -c
|
|
oom-sort --cmdline 20
|
|
watch oom-sort
|
|
'''
|
|
|
|
|
|
parser = ArgumentParser()
|
|
|
|
parser.add_argument(
|
|
'--number',
|
|
'-n',
|
|
help="""number of lines; integer, not negative; 0 - unlimited; unlimited by default""",
|
|
default=None,
|
|
type=str
|
|
)
|
|
|
|
parser.add_argument(
|
|
'--cmdline',
|
|
'-c',
|
|
help="""display cmdlines""",
|
|
default=None,
|
|
type=str
|
|
)
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
display_cmdline = args.cmdline
|
|
num_lines = args.number
|
|
|
|
|
|
if num_lines == None:
|
|
num_lines = 99999
|
|
|
|
|
|
if display_cmdline == None:
|
|
display_cmdline = 9999
|
|
|
|
|
|
|
|
|
|
|
|
#print([num_lines], [display_cmdline])
|
|
|
|
|
|
|
|
|
|
|
|
def human(num):
|
|
'''KiB to MiB'''
|
|
return str(round(num / 1024.0)).rjust(6, ' ')
|
|
|
|
|
|
with open('/proc/self/status') as file:
|
|
status_list = file.readlines()
|
|
|
|
# список имен из /proc/*/status для дальнейшего поиска позиций VmRSS and VmSwap
|
|
status_names = []
|
|
for s in status_list:
|
|
status_names.append(s.split(':')[0])
|
|
|
|
vm_rss_index = status_names.index('VmRSS')
|
|
vm_swap_index = status_names.index('VmSwap')
|
|
uid_index = status_names.index('Uid')
|
|
|
|
oom_list = []
|
|
for pid in listdir('/proc'):
|
|
# пропускаем элементы, состоящие не из цифр и PID 1
|
|
if pid.isdigit() is not True or pid == '1':
|
|
continue
|
|
try:
|
|
with open('/proc/' + pid + '/cmdline') as file:
|
|
try:
|
|
cmdline = file.readlines()[0].replace('\x00', ' ')
|
|
except IndexError:
|
|
continue
|
|
with open('/proc/' + pid + '/oom_score') as file:
|
|
oom_score = int(file.readlines()[0][:-1])
|
|
with open('/proc/' + pid + '/oom_score_adj') as file:
|
|
oom_score_adj = int(file.readlines()[0][:-1])
|
|
except FileNotFoundError:
|
|
continue
|
|
except ProcessLookupError:
|
|
continue
|
|
|
|
oom_list.append((pid, oom_score, oom_score_adj, cmdline))
|
|
|
|
# list sorted by oom_score
|
|
oom_list_sorted = sorted(oom_list, key=itemgetter(1), reverse=True)
|
|
|
|
print('oom_score oom_score_adj Uid Pid Name VmRSS VmSwap cmdline')
|
|
print('--------- ------------- ----- ----- --------------- -------- -------- -------')
|
|
|
|
# итерируемся по сортированному списку oom_score, печатая name, pid etc
|
|
for i in oom_list_sorted[:int(num_lines)]:
|
|
pid = i[0]
|
|
oom_score = i[1]
|
|
oom_score_adj = i[2]
|
|
cmdline = i[3].strip()
|
|
|
|
try:
|
|
# читать часть файла не дальше VmSwap - когда-нибудь
|
|
with open('/proc/' + pid + '/status') as file:
|
|
status_list = file.readlines()
|
|
|
|
vm_rss = int(status_list[vm_rss_index].split(':')[1].split(' ')[-2])
|
|
vm_swap = int(status_list[vm_swap_index].split(':')[1].split(' ')[-2])
|
|
name = status_list[0][:-1].split('\t')[1]
|
|
uid = status_list[uid_index].split('\t')[1]
|
|
|
|
except FileNotFoundError:
|
|
continue
|
|
|
|
except ProcessLookupError:
|
|
continue
|
|
|
|
print(
|
|
'{} {} {} {} {} {} M {} M {}'.format(
|
|
str(oom_score).rjust(9),
|
|
str(oom_score_adj).rjust(13),
|
|
uid.rjust(5),
|
|
str(pid).rjust(5),
|
|
name.ljust(15),
|
|
human(vm_rss),
|
|
human(vm_swap),
|
|
cmdline[:int(display_cmdline)]
|
|
)
|
|
)
|