monit: проверить процесс без pidfile

37

Я ищу способ убить все процессы с заданным именем, которые выполняются более X раз. Я порождаю много экземпляров этого конкретного исполняемого файла, и иногда он переходит в плохое состояние и работает вечно, занимая много процессора.

Я уже использую monit, но я не знаю, как проверить процесс без pid-файла. Правило будет примерно таким:

kill all processes named xxxx that have a running time greater than 2 minutes

Как бы вы выразили это в monit?

Parand
источник
( Вы должны отметить здесь ответ )
ewwhite

Ответы:

80

В monit вы можете использовать соответствующую строку для процессов, которые не имеют PID. Используя пример процесса с именем «myprocessname»,

check process myprocessname
        matching "myprocessname"
        start program = "/etc/init.d/myproccessname start"
        stop program = "/usr/bin/killall myprocessname"
        if cpu usage > 95% for 10 cycles then restart

Возможно, если вы проверите, находится ли загрузка ЦП на определенном уровне в течение 10 циклов мониторинга (по 30 секунд каждый), то перезапустите или убейте, что может быть вариантом. Или вы можете использовать временную проверку monit для файла, связанного с процессом.

ewwhite
источник
1
Будьте осторожны: это не сработает, если существует более одного процесса
ruX
1
Вы можете использовать регулярное выражение: matchin "otherstuff. * myprocessname"
user174962
@ruX: что произойдет, если несколько связанных процессов совпадают? Как они могут обращаться?
kontextify
Требуется первый матч.
Ewwhite
5

Там нет готового к использованию инструмента с такой функциональностью. Предположим, вы хотите уничтожить скрипты php-cgi, которые работают дольше минуты. Сделай это:

pgrep php-cgi | xargs ps -o pid,time | perl -ne 'print "$1 " if /^\s*([0-9]+) ([0-9]+:[0-9]+:[0-9]+)/ && $2 gt "00:01:00"' | xargs kill

pgrepвыбирает процессы по имени, ps -o pid,timeпечатает время выполнения для каждого pid, а затем анализирует строку, извлекает из нее время и печатает pid, если время сравнивается с заданным. Результат передан, чтобы убить.

datacompboy
источник
процесс, выполняющийся в течение очень долгого времени, получает странное время выполнения (62-13: 53: 05), поэтому время анализа регулярного выражения должно быть ([-0-9] +: [0-9] +: [0-9] + ) - посмотрите на минус в начале выражения.
Андрей
3

Я решил эту проблему с помощью ps-watcher и написал об этом на linux.com несколько лет назад. ps-watcher позволяет вам отслеживать процессы и уничтожать их в зависимости от накопленного времени выполнения. Вот соответствующая конфигурация ps-watcher, предполагая, что ваш процесс называется 'foo':

[foo]
  occurs = every
  trigger = elapsed2secs('$time') > 1*HOURS && $ppid != 1
  action = <<EOT
  echo "$command accumulated too much CPU time" | /bin/mail user\@host
  kill -TERM $pid
EOT

[foo?]
   occurs = none
   action = /usr/local/etc/foo restart

Ключ это линия

trigger = elapsed2secs('$time') > 1*HOURS && $ppid != 1`

который говорит: «если накопленное время процесса> 1 часа И я не родительский процесс, перезапустите меня.

Итак, я понимаю, что в ответе не используется monit, но он работает. ps-watcher легок и прост в настройке, так что нет ничего плохого в том, чтобы запускать его в дополнение к настройке вашего монитора.

Фил Холленбек
источник
0

Вы можете превратить это в monit как выражение exec.

    if [[ "$(uname)" = "Linux" ]];then killall --older-than 2m someprocessname;fi
Джоди С
источник