monit: Überprüfe den Prozess ohne PID-Datei

36

Ich suche nach einer Möglichkeit, alle Prozesse mit einem bestimmten Namen zu beenden, die länger als die Hälfte der Zeit ausgeführt wurden. Ich spawne viele Instanzen dieser bestimmten ausführbaren Datei, und manchmal geht sie in einen schlechten Zustand über und läuft für immer, wobei sie viel CPU aufnimmt.

Ich verwende bereits Monit, kann aber nicht nach einem Prozess ohne PID-Datei suchen. Die Regel wäre etwa so:

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

Wie würden Sie dies in Monit ausdrücken?

Parand
quelle
( du solltest hier eine Antwort
ankreuzen

Antworten:

80

In monit können Sie für Prozesse ohne PID eine übereinstimmende Zeichenfolge verwenden. Am Beispiel eines Prozesses mit dem Namen "meinProzessname"

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

Wenn Sie überprüfen, ob die CPU-Auslastung für 10 Überwachungszyklen (jeweils 30 Sekunden) auf einem bestimmten Niveau liegt, starten Sie den Computer möglicherweise neu oder beenden Sie ihn. Dies kann eine Option sein. Oder Sie können den Zeitstempeltest von monit für eine Datei verwenden, die sich auf den Prozess bezieht.

ewwhite
quelle
1
Seien Sie vorsichtig: Es wird nicht funktionieren, es gibt mehr als einen Prozess
ruX
1
Sie können einen regulären Ausdruck verwenden: matchin "otherstuff. * myprocessname"
user174962
@ruX: Was passiert, wenn mehrere verwandte Prozesse übereinstimmen? Wie können sie gehandhabt werden?
kontextify
Es dauert das erste Spiel.
Ewwhite
5

Es gibt kein einsatzbereites Tool mit dieser Funktionalität. Nehmen wir an, Sie möchten PHP-CGI-Skripte beenden, die länger als eine Minute dauern. Mach das:

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

pgrepwählt Prozesse nach Namen aus, gibt die ps -o pid,timeLaufzeit für jede PID aus und analysiert dann die Zeile, extrahiert die Zeit daraus und gibt die PID aus, wenn die Zeit mit der definierten Zeit verglichen wird. Ergebnis übergeben, um zu töten.

datacompboy
quelle
Der Prozess, der für sehr lange Zeit ausgeführt wird, erhält eine merkwürdige Laufzeit (62-13: 53: 05), daher sollte die Laufzeit für das Analysieren von Regexp ([-0-9] +: [0-9] +: [0-9] + sein ) - Sehen Sie sich das Minus am Anfang des Ausdrucks an.
Andrej
3

Ich habe genau dieses Problem mit ps-watcher gelöst und vor ein paar Jahren auf linux.com darüber geschrieben . Mit ps-watcher können Sie Prozesse überwachen und sie basierend auf der akkumulierten Laufzeit beenden. Hier ist die relevante Konfiguration von ps-watcher, vorausgesetzt, Ihr Prozess heißt '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

Der Schlüssel ist die Linie

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

Hier steht 'Wenn die akkumulierte Prozesszeit> 1 Stunde ist UND ich nicht der übergeordnete Prozess bin, starte mich neu.

Mir ist also klar, dass die Antwort kein Monit verwendet, aber funktioniert. ps-watcher ist leicht und einfach einzurichten, so dass es keinen Schaden anrichtet, es zusätzlich zu Ihrem Monit-Setup zu betreiben.

Phil Hollenback
quelle
3

Monit kann dies ab Version 5.4:

if uptime > 3 days then restart

Siehe: das Projekt CHANGES-Datei

David Radcliffe
quelle
0

Sie können dies als exec-Anweisung in monit einarbeiten.

    if [[ "$(uname)" = "Linux" ]];then killall --older-than 2m someprocessname;fi
Jodie C
quelle