support EXECUTE THE COMMAND INSTEAD OF SENDING THE SIGTERM SIGNAL
This commit is contained in:
parent
9bebbe38f9
commit
c5a9478cd5
@ -74,6 +74,7 @@ https://www.reddit.com/r/linux/comments/5rixe9/this_is_why_i_love_linux_hundreds
|
||||
- возможность показа десктопных уведомлений c помощью `notify-send`, с показом сигнала (`SIGTERM` или `SIGKILL`), который отправлен процессу, а также `Pid`, `oom_score`, `VmRSS`, `VmSwap`, которыми обладал процесс перед получением сигнала.
|
||||
- поддержка white, black, prefer и avoid списков с использованием Perl-compatible regular expressions
|
||||
- наличие `man` страницы
|
||||
- возможность выполнения определенных команд как альтернатива отправке SIGTERM для избранных процессов (можно использовать для перезапуска демонов вместо завершения)
|
||||
- поддержка журналирования в отдельный файл
|
||||
- поддержка десктопных уведомлений о низком уровне доступной памяти
|
||||
- наличие установщика для пользователей `systemd`
|
||||
|
73
nohang
73
nohang
@ -411,26 +411,35 @@ def find_victim_and_send_signal(signal):
|
||||
vm_rss = 0
|
||||
vm_swap = 0
|
||||
|
||||
try_to_send = ' Preventing OOM: trying to send the {} signal to {},\n Pid: {}, Badness: {}, VmRSS: {} MiB, VmSwap: {} MiB'.format(sig_dict[signal], name, pid, oom_score, vm_rss, vm_swap)
|
||||
|
||||
print(try_to_send)
|
||||
if name in etc_dict and signal is 15:
|
||||
command = etc_dict[name]
|
||||
etc_info = ' Process {} is a victim,\n Pid: {}, Badness: {}, VmRSS: {} MiB, VmSwap: {} MiB\n Execute command: {}'.format(name, pid, oom_score, vm_rss, vm_swap, command)
|
||||
print(etc_info)
|
||||
os.system(etc_dict[name])
|
||||
append_log(etc_info)
|
||||
|
||||
try:
|
||||
os.kill(int(pid), signal)
|
||||
send_result = ' Success'
|
||||
else:
|
||||
try_to_send = ' Preventing OOM: trying to send the {} signal to {},\n Pid: {}, Badness: {}, VmRSS: {} MiB, VmSwap: {} MiB'.format(sig_dict[signal], name, pid, oom_score, vm_rss, vm_swap)
|
||||
|
||||
if desktop_notifications:
|
||||
send_notify(signal, name, pid, oom_score, vm_rss, vm_swap)
|
||||
print(try_to_send)
|
||||
|
||||
except FileNotFoundError:
|
||||
send_result = ' No such process'
|
||||
except ProcessLookupError:
|
||||
send_result = ' No such process'
|
||||
try:
|
||||
os.kill(int(pid), signal)
|
||||
send_result = ' Success'
|
||||
|
||||
print(send_result)
|
||||
if desktop_notifications:
|
||||
send_notify(signal, name, pid, oom_score, vm_rss, vm_swap)
|
||||
|
||||
if logging:
|
||||
append_log(try_to_send + '\n' + send_result)
|
||||
except FileNotFoundError:
|
||||
send_result = ' No such process'
|
||||
except ProcessLookupError:
|
||||
send_result = ' No such process'
|
||||
|
||||
print(send_result)
|
||||
|
||||
if logging:
|
||||
append_log(try_to_send + '\n' + send_result)
|
||||
|
||||
else:
|
||||
|
||||
@ -547,17 +556,40 @@ print(config)
|
||||
|
||||
# парсинг конфига с получением словаря параметров
|
||||
|
||||
# conf_parameters_dict
|
||||
# conf_restart_dict
|
||||
|
||||
try:
|
||||
with open(config) as f:
|
||||
|
||||
# словарь с параметрами конфига
|
||||
config_dict = dict()
|
||||
|
||||
# словарь с именами и командами для параметра execute_the_command
|
||||
etc_dict = dict()
|
||||
|
||||
for line in f:
|
||||
|
||||
a = line.startswith('#')
|
||||
b = line.startswith('\n')
|
||||
c = line.startswith('\t')
|
||||
d = line.startswith(' ')
|
||||
if not a and not b and not c and not d:
|
||||
|
||||
etc = line.startswith('**')
|
||||
|
||||
if not a and not b and not c and not d and not etc:
|
||||
a = line.split('=')
|
||||
config_dict[a[0].strip()] = a[1].strip()
|
||||
|
||||
if etc:
|
||||
a = line[2:].split('::')
|
||||
etc_name = a[0].strip()
|
||||
etc_command = a[1].strip()
|
||||
if len(etc_name) > 15:
|
||||
print('инвалид конфиг, длина имени процесса не должна превышать 15 символов\nExit')
|
||||
exit()
|
||||
etc_dict[etc_name] = etc_command
|
||||
|
||||
except PermissionError:
|
||||
print('PermissionError', conf_err_mess)
|
||||
exit()
|
||||
@ -1087,6 +1119,9 @@ else:
|
||||
exit()
|
||||
|
||||
|
||||
execute_the_command = conf_parse_bool('execute_the_command')
|
||||
|
||||
|
||||
##########################################################################
|
||||
|
||||
# получение уровней в кибибайтах
|
||||
@ -1266,6 +1301,14 @@ if print_config:
|
||||
round(zram_max_warnings_mb), round(zram_max_warnings_percent, 1)))
|
||||
|
||||
|
||||
print('\nX. EXECUTE THE COMMAND INSTEAD OF SENDING THE SIGTERM SIGNAL')
|
||||
print('execute_the_command: {}'.format(execute_the_command))
|
||||
if execute_the_command:
|
||||
print('\nPROCESS NAME COMMAND TO EXECUTE')
|
||||
for key in etc_dict:
|
||||
print('{} {}'.format(key.ljust(15), etc_dict[key]))
|
||||
|
||||
|
||||
##########################################################################
|
||||
|
||||
|
||||
|
33
nohang.conf
33
nohang.conf
@ -20,7 +20,7 @@ print_config = True
|
||||
Печатать ли результаты измерения доступной памяти.
|
||||
Допустимые значения: True и False
|
||||
|
||||
print_mem_check_results = False
|
||||
print_mem_check_results = True
|
||||
|
||||
Печатать ли время сна между проверками памяти и после отправки
|
||||
сигналов. Можно установить в значение True для дебага.
|
||||
@ -94,8 +94,8 @@ rate_zram = 1
|
||||
mem_min_sigterm = 8 %
|
||||
mem_min_sigkill = 4 %
|
||||
|
||||
swap_min_sigterm = 8 %
|
||||
swap_min_sigkill = 4 %
|
||||
swap_min_sigterm = 50 %
|
||||
swap_min_sigkill = 20 %
|
||||
|
||||
Задание общей доли zram в памяти, при превышении которой
|
||||
происходит отправка соответствующих сигналов.
|
||||
@ -278,3 +278,30 @@ swap_min_warnings = 20%
|
||||
|
||||
zram_max_warnings = 40 %
|
||||
|
||||
#####################################################################
|
||||
|
||||
X. EXECUTE THE COMMAND INSTEAD OF SENDING THE SIGTERM SIGNAL
|
||||
|
||||
Для процессов с определенным именем можно задать команду,
|
||||
которая будет выполняться вместо отправки сигнала SIGTERM
|
||||
процессу с соответствующим именем.
|
||||
|
||||
Например, если процесс запущен как демон, то вместо
|
||||
отправки SIGTERM можно выполнить команду перезапуска.
|
||||
|
||||
Допустимые значения: True и False.
|
||||
|
||||
execute_the_command = False
|
||||
|
||||
Длина имени процесса не должна превышать 15 символов.
|
||||
Синтаксис таков: строки, начинающиеся с **, считаются строками,
|
||||
содержащими имена процессов и соотвестствующие команды для
|
||||
перезапуска этих процессов. После имени процесса через двойное
|
||||
двоеточие (::) следует команда.
|
||||
Например:
|
||||
** mysqld :: systemctl restart mariadb.service &
|
||||
** php-fpm7.0 :: systemctl restart php7.0-fpm.service &
|
||||
Амперсанд (&) в конце команды позволит nohang продолжить работу
|
||||
не дожидаясь окончания выполнения команды.
|
||||
|
||||
** processname :: some command &
|
||||
|
Loading…
Reference in New Issue
Block a user