support logging to separate file and support low memory warnings

This commit is contained in:
Alexey Avramov 2018-07-03 00:08:02 +09:00
parent 8825021f6b
commit e5fb5db7bd
8 changed files with 816 additions and 505 deletions

View File

@ -31,6 +31,9 @@ https://www.linux.org.ru/forum/talks/12684213?lastmod=1466676523241#comment-1268
"И IRL ты никогда не знаешь, в какой момент момент твои данные перестанут умещаться в оперативку. Потому zram -- удел embedded систем, где это может быть детерминировано." "И IRL ты никогда не знаешь, в какой момент момент твои данные перестанут умещаться в оперативку. Потому zram -- удел embedded систем, где это может быть детерминировано."
https://2ch.hk/s/res/2310304.html#2311483, https://archive.li/idixk https://2ch.hk/s/res/2310304.html#2311483, https://archive.li/idixk
"OOM killer, зараза такая, не срабатывает или срабатывает через 3 часа."
https://www.linux.org.ru/forum/desktop/11255705
`Nohang` позволяет избавиться от перечисленных выше проблем, корректно завершая наиболее прожорливые процессы (с наибольшим oom_score) сигналом `SIGTERM` (или `SIGKILL`) не дожидаясь когда система "встанет колом". `Nohang` позволяет не бояться зависаний при использовании `zram`. `Nohang` позволяет избавиться от перечисленных выше проблем, корректно завершая наиболее прожорливые процессы (с наибольшим oom_score) сигналом `SIGTERM` (или `SIGKILL`) не дожидаясь когда система "встанет колом". `Nohang` позволяет не бояться зависаний при использовании `zram`.
### Зачем нужен nohang, если уже есть earlyoom? ### Зачем нужен nohang, если уже есть earlyoom?
@ -59,18 +62,21 @@ https://2ch.hk/s/res/2310304.html#2311483, https://archive.li/idixk
- возможность показа десктопных уведомлений c помощью `notify-send`, с показом сигнала (`SIGTERM` или `SIGKILL`), который отправлен процессу, а также `Pid`, `oom_score`, `VmRSS`, `VmSwap`, которыми обладал процесс перед получением сигнала. - возможность показа десктопных уведомлений c помощью `notify-send`, с показом сигнала (`SIGTERM` или `SIGKILL`), который отправлен процессу, а также `Pid`, `oom_score`, `VmRSS`, `VmSwap`, которыми обладал процесс перед получением сигнала.
- поддержка white, black, prefer и avoid списков с использованием Perl-compatible regular expressions - поддержка white, black, prefer и avoid списков с использованием Perl-compatible regular expressions
- наличие `man` страницы - наличие `man` страницы
- поддержка журналирования в отдельный файл
- поддержка десктопных уведомлений о низком уровне доступной памяти
- наличие установщика для пользователей `systemd` - наличие установщика для пользователей `systemd`
- протестировано на `Debian 9 x86_64`, `Debian 8 i386`, `Fedora 28 x86_64` - протестировано на `Debian 9 x86_64`, `Debian 8 i386`, `Fedora 28 x86_64`
- пример вывода с отчетом об успешной отпраке сигнала: - пример вывода с отчетом об успешной отпраке сигнала:
``` ```
MemAvail: 0 M, 0.0 % | SwapFree: 97 M, 8.3 % | MemUsedZram: 147 M, 2.5 % 2018-07-02 Mon 16:51:20
MemAvail: 0 M, 0.0 % | SwapFree: 80 M, 6.8 % | MemUsedZram: 147 M, 2.5 % MemAvailable (0 MiB, 0.0 %) < mem_min_sigterm (470 MiB, 8.0 %)
+ MemAvail (0 M, 0.0 %) < mem_min_sigterm (470 M, 8.0 %) SwapFree (646 MiB, 5.5 %) < swap_min_sigterm (940 MiB, 8.0 %)
SwapFree (80 M, 6.8 %) < swap_min_sigterm (94 M, 8.0 %) Xorg (Pid: 11722) matches with whitelist_regex
Try to send signal 15 to tail, Pid 17907, oom_score 837 python3 (Pid: 26844, Badness 3) matches with preferlist_regex
tail (Pid: 26845, Badness 2700) matches with preferlist_regex
Preventing OOM: trying to send the SIGTERM signal to tail,
Pid: 26845, Badness: 2700, VmRSS: 5033 MiB, VmSwap: 10797 MiB
Success Success
MemAvail: 640 M, 10.9 % | SwapFree: 730 M, 62.1 % | MemUsedZram: 141 M, 2.4 %
MemAvail: 5197 M, 88.5 % | SwapFree: 734 M, 62.5 % | MemUsedZram: 141 M, 2.4 %
``` ```
### Установка и удаление для пользователей systemd ### Установка и удаление для пользователей systemd

View File

@ -1,4 +1,4 @@
#!/bin/bash -v #!/bin/sh -v
cp nohang /usr/local/bin/ cp nohang /usr/local/bin/
chmod 755 /usr/local/bin/nohang chmod 755 /usr/local/bin/nohang
@ -15,6 +15,12 @@ cp nohang.1.gz /usr/local/share/man/man1/
chmod 644 /usr/local/share/man/man1/nohang.1.gz chmod 644 /usr/local/share/man/man1/nohang.1.gz
rm nohang.1.gz rm nohang.1.gz
mkdir /var/log/nohang
chmod 750 /var/log/nohang
cp nohang.logrotate /etc/logrotate.d/nohang
chmod 644 /etc/logrotate.d/nohang
cp nohang.service /etc/systemd/system/ cp nohang.service /etc/systemd/system/
chmod 644 /etc/systemd/system/nohang.service chmod 644 /etc/systemd/system/nohang.service
systemctl daemon-reload systemctl daemon-reload

1123
nohang

File diff suppressed because it is too large Load Diff

View File

@ -2,12 +2,15 @@
Nohang config file Nohang config file
Комментариями являются строки, начинающиеся с решёток, пробелов Комментариями являются строки, начинающиеся с решёток, пробелов
и табуляций. Инлайновые комментарии запрещены. Пробелы допустиы и табуляций. Инлайновые комментарии запрещены.
внутри строк в любом количестве. Пробелы допустимы внутри строк в любом количестве.
Все параметры, кроме строковых (display, notify_options,
*list_regex), проходят проверку на допустимые значения.
##################################################################### #####################################################################
I. VERBOSITY I. STANDARD OUTPUT VERBOSITY
Печатать параметров конфига при запуске программы. Печатать параметров конфига при запуске программы.
Допустимые значения: True и False Допустимые значения: True и False
@ -17,18 +20,17 @@ print_config = True
Печатать ли результаты измерения доступной памяти. Печатать ли результаты измерения доступной памяти.
Допустимые значения: True и False Допустимые значения: True и False
print_mem_check_results = True print_mem_check_results = False
Печатать ли время сна между проверками памяти и после отправки Печатать ли время сна между проверками памяти и после отправки
сигналов. Можно установить в значение True для дебага. сигналов. Можно установить в значение True для дебага.
Допустимые значения: True и False Допустимые значения: True и False
(В этой ветке по дефолту True)
print_sleep_periods = False print_sleep_periods = False
##################################################################### #####################################################################
II. SELF PROTECTION II. SELF-DEFENSE
True - заблокировать процесс в памяти для запрета его своппинга. True - заблокировать процесс в памяти для запрета его своппинга.
False - не блокировать. Значения чувствительны к регистру! False - не блокировать. Значения чувствительны к регистру!
@ -36,7 +38,7 @@ print_sleep_periods = False
В Fedora 28 значение True вызывает увеличение потребления В Fedora 28 значение True вызывает увеличение потребления
памяти процессом на 200 MiB, в Debian 8 и 9 такой проблемы нет. памяти процессом на 200 MiB, в Debian 8 и 9 такой проблемы нет.
mlockall = False mlockall = True
Установка отрицательных значений self_nice и self_oom_score_adj Установка отрицательных значений self_nice и self_oom_score_adj
требует наличия root прав. требует наличия root прав.
@ -54,7 +56,7 @@ self_oom_score_adj = -1000
##################################################################### #####################################################################
III. ИНТЕНСИВНОСТЬ МОНИТОРИНГА III. MONITORING INTENSITY
Коэффициенты, влияющие на интенсивность мониторинга. Коэффициенты, влияющие на интенсивность мониторинга.
Допустимыми значениями являются положительные числа. Допустимыми значениями являются положительные числа.
@ -69,15 +71,15 @@ self_oom_score_adj = -1000
В дефолтных настройках на данной интенсивности демон работает В дефолтных настройках на данной интенсивности демон работает
достаточно хорошо, успешно справляясь с резкими скачками потребления достаточно хорошо, успешно справляясь с резкими скачками потребления
памяти. памяти.
rate_mem = 6000000 rate_mem = 6
rate_swap = 3000000 rate_swap = 3
rate_zram = 1000000 rate_zram = 1
##################################################################### #####################################################################
IV. ПОРОГИ ДЛЯ ОТПРАВКИ СИГНАЛОВ IV. THRESHOLDS FOR SENDING SIGNALS
Задание уровней доступной памяти, ниже которых происходит Задание уровней доступной памяти, ниже которых происходит
отправка сигналов SIGTERM или SIGKILL. отправка сигналов SIGTERM или SIGKILL.
@ -87,6 +89,8 @@ rate_zram = 1000000
Значения могут быть выражены в процентах (%) и мебибайтах (M) Значения могут быть выражены в процентах (%) и мебибайтах (M)
Диапазон допустимых значений - от 0 до 100 %.
mem_min_sigterm = 8 % mem_min_sigterm = 8 %
mem_min_sigkill = 4 % mem_min_sigkill = 4 %
@ -100,13 +104,15 @@ swap_min_sigkill = 4 %
По мере увеличения доли zram в памяти может падать По мере увеличения доли zram в памяти может падать
отзывчивость системы. отзывчивость системы.
Может также задаваться в % и M. Может также задаваться в % и M.
Диапазон допустимых значений - от 0 до 100% (90% - это обычно
уровень зависания или срабатывания OOM killer'a)
zram_max_sigterm = 55 % zram_max_sigterm = 55 %
zram_max_sigkill = 60 % zram_max_sigkill = 60 %
##################################################################### #####################################################################
V. THE PREVENTION OF KILLING INNOCENT VICTIMS V. PREVENTION OF KILLING INNOCENT VICTIMS
Минимальное значение oom_score, которым должен обладать Минимальное значение oom_score, которым должен обладать
процесс для того, чтобы ему был отправлен сигнал. процесс для того, чтобы ему был отправлен сигнал.
@ -115,9 +121,6 @@ zram_max_sigkill = 60 %
Значение должно быть целым числом из диапазона [0; 1000] Значение должно быть целым числом из диапазона [0; 1000]
Процессы из black_list (см ниже) получат сигнал вне зависимости
от значения их oom_score.
Может min_badness с учетом списков? Может min_badness с учетом списков?
oom_score_min = 20 oom_score_min = 20
@ -141,7 +144,7 @@ min_delay_after_sigkill = 3
Требует root прав. Требует root прав.
decrease_oom_score_adj = False decrease_oom_score_adj = True
Допустимые значения - целые числа из диапазона [0; 1000] Допустимые значения - целые числа из диапазона [0; 1000]
@ -170,46 +173,108 @@ desktop_notifications = True
notify_options = notify_options =
Переменая окружения $DISPLAY, передаваемая notify-send при
запуске nohang с uid = 0.
Должен совпадать с выводом Должен совпадать с выводом
$ echo $DISPLAY $ echo $DISPLAY
display = :0 root_display = :0
##################################################################### #####################################################################
VII. BLACK, WHITE, AVOID AND PREFER LISTS VII. BLACK, WHITE, AVOID AND PREFER LISTS
Можно задать списки с помощью Perl-compatible regular expressions. Можно задать регулярные выражения (Perl-compatible regular
expressions), которые будут использоваться для сопоставления с
именами процессов для влияния на их badness.
Включение этой опции замедляет поиск жертвы, так как Включение этой опции замедляет поиск жертвы, так как
имена всех процессов сравниваются с regexp паттернами всех имена всех процессов сравниваются с заданными regex-паттернами.
списков.
use_regexp_lists = False use_regex_lists = False
Процессы из белого списка не получат сигнал. Приоритет списков (если один процесс находится одновременно в
нескольких):
1. whitelist_regex: сначала пропуск процессов из белого списка;
2. blacklist_regex: отправка сигнала всем из черного списка;
3. preferlist_regex и avoidlist_regex: умножение или деление
oom_score на соответствующие факторы.
white_list = ^(Xorg|sshd)$ Процессы, имена которых соответствуют выражению
whitelist_regex, не получат сигнал.
При нехватке памяти все процессы из черного списка получат сигнал. Регулярное выражение для формирования белого списка.
black_list = ^()$ whitelist_regex = Xorg|sshd
Список предпочтительных для убийства процессов. При нехватке памяти все процессы, имена которых соответствуют
Badness процессов из prefer_list будет умножено на blacklist_regex, получат сигнал.
prefer_factor перед выбором жертвы. На самом деле формула
для нахождения badness такая:
badness = (oom_score + 1) * prefer_factor
prefer_factor и avoid_factor должны быть положительными числами. blacklist_regex =
prefer_list = ^()$ Badness процессов, имена которых соответствуют preferlist_regex,
prefer_factor = 2 будут рассчитываться по формуле
badness = (oom_score + 1) * preferlist_factor
preferlist_regex = tail|python3
Диапазон допустимых значений: [1; 1000]
preferlist_factor = 3
Список нежелательных для убийства процессов. Список нежелательных для убийства процессов.
Badness процессов из avoid_list будет поделено на
avoid_factor перед выбором жертвы.
avoid_list = ^()$ Badness процессов, имена которых соответствуют avoidlist_regex,
avoid_factor = 2 будут рассчитываться по формуле
badness = oom_score / avoidlist_factor
avoidlist_regex =
Диапазон допустимых значений: [1; 1000]
avoidlist_factor = 3
#####################################################################
VIII. LOGGING
В лог записывается дата, объемы доступной памяти и ход
предотвращения OOM.
Valid values are True and False.
logging = True
logfile = /var/log/nohang/nohang.log
#####################################################################
IX. LOW MEMORY WARNINGS
Десктопные уведомления о низком уровне доступной памяти.
Для работы опции должны быть включены десктопные уведомления.
Возможно стоит этот раздел объединить с DESKTOP NOTIFICATIONS.
Valid values are True and False.
low_memory_warnings = True
Минимальное время между отправками уведомлений в секундах.
Должно быть в диапазоне [1; 300].
min_time_between_warnings = 20
Уровни MemAvailable и SwapFree одновременно будут ниже
соотвестствующих значений, то будут отправлены уведомления.
Могут быть выражены в процентах (%) и мебибайтах (M).
mem_min_warnings = 20 %
swap_min_warnings = 20%
Если доля zram в памяти превысит значение zram_max_warnings,
то будут отправляться уведомления с минимальным периодом
min_time_between_warnings.
zram_max_warnings = 40 %

9
nohang.logrotate Normal file
View File

@ -0,0 +1,9 @@
/var/log/nohang/*.log {
create 640 root adm
missingok
notifempty
weekly
rotate 5
compress
delaycompress
}

View File

@ -7,6 +7,8 @@ Documentation=man:nohang(1) https://github.com/hakavlad/nohang
[Service] [Service]
Type=simple Type=simple
Restart=always Restart=always
StandardOutput=null
StandardError=syslog
ExecStart=/usr/local/bin/nohang ExecStart=/usr/local/bin/nohang
[Install] [Install]

View File

@ -1,7 +1,9 @@
#!/bin/bash -v #!/bin/sh -v
systemctl stop nohang systemctl stop nohang
systemctl disable nohang systemctl disable nohang
rm /usr/local/bin/nohang
rm /usr/local/share/man/man1/nohang.1.gz rm /usr/local/share/man/man1/nohang.1.gz
rm /etc/systemd/system/nohang.service rm /etc/systemd/system/nohang.service
rm /etc/logrotate.d/nohang
rm -r /etc/nohang rm -r /etc/nohang
rm /usr/local/bin/nohang rm -r /var/log/nohang

View File

@ -1,6 +1,8 @@
#!/bin/bash -v #!/bin/sh -v
systemctl stop nohang systemctl stop nohang
systemctl disable nohang systemctl disable nohang
rm -f /usr/local/share/man/man1/nohang.1.gz rm /usr/local/bin/nohang
rm -f /etc/systemd/system/nohang.service rm /usr/local/share/man/man1/nohang.1.gz
rm -f /usr/local/bin/nohang rm /etc/systemd/system/nohang.service
rm /etc/logrotate.d/nohang
rm -r /var/log/nohang