monit: sprawdzanie procesu bez pliku pid

36

Szukam sposobu na zabicie wszystkich procesów o podanej nazwie, które działały przez ponad X czasu. Odradzam wiele wystąpień tego konkretnego pliku wykonywalnego, a czasem przechodzi on w zły stan i działa wiecznie, zajmując dużo procesora.

Już używam monit, ale nie wiem, jak sprawdzić proces bez pliku pid. Reguła byłaby mniej więcej taka:

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

Jak wyraziłbyś to w monit?

Parand
źródło
(tutaj należy zaznaczyć odpowiedź )
ewwhite

Odpowiedzi:

80

W monit możesz użyć pasującego łańcucha dla procesów, które nie mają PID. Korzystając z przykładu procesu o nazwie „mojaprocesa”,

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

Być może, jeśli sprawdzisz, czy obciążenie procesora jest na określonym poziomie przez 10 cykli monitorowania (po 30 sekund), a następnie uruchom ponownie lub zabij, może to być opcja. Lub możesz użyć testu sygnatury czasowej monitora dla pliku związanego z procesem.

ewwhite
źródło
1
Uważaj: to nie zadziała, istnieje więcej niż jeden proces
ruX
1
możesz użyć wyrażenia regularnego: matchin „otherstuff. * myprocessname”
user174962
@ruX: co się stanie, jeśli dopasowanych zostanie wiele powiązanych procesów? Jak sobie z tym poradzić?
kontextify
To trwa pierwszy mecz.
ewwhite
5

Nie ma gotowego do użycia narzędzia z taką funkcjonalnością. Załóżmy, że chcesz zabić skrypty php-cgi, które działają dłużej niż minutę. Zrób to:

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

pgrepwybierze procesy według nazwy, ps -o pid,timedrukuje środowisko wykonawcze dla każdego pid, a następnie analizuje linię, wyodrębnia z niej czas i drukuje pid, jeśli czas porównuje się z określonym. wynik przekazany do zabicia.

datacompboy
źródło
uruchamianie procesu przez bardzo długi czas staje się dziwne (62-13: 53: 05), więc czas przetwarzania analizy regularnej powinien wynosić ([-0-9] +: [0-9] +: [0-9] + ) - spójrz na minus na początku wyrażenia.
andrej
3

Dokładnie rozwiązałem ten problem z ps- watcherem i pisałem o tym na linux.com kilka lat temu. ps-watcher pozwala monitorować procesy i zabijać je na podstawie skumulowanego czasu działania. Oto odpowiednia konfiguracja ps-watcher, zakładając, że twój proces nazywa się „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

Kluczem jest linia

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

co mówi: „jeśli skumulowany czas procesu wynosi> 1 godzina ORAZ nie jestem procesem nadrzędnym, uruchom mnie ponownie.

Zdaję sobie sprawę, że odpowiedź nie korzysta z monitora, ale działa. ps-watcher jest lekki i prosty w konfiguracji, więc korzystanie z niego oprócz konfiguracji monitorowania nie jest szkodliwe.

Phil Hollenback
źródło
3

Monit może to zrobić od wersji 5.4:

if uptime > 3 days then restart

Zobacz: plik ZMIANY projektu

David Radcliffe
źródło
0

Możesz to przetworzyć w monit jako instrukcję exec.

    if [[ "$(uname)" = "Linux" ]];then killall --older-than 2m someprocessname;fi
Jodie C.
źródło