web-dev-qa-db-fra.com

monit: vérifier le processus sans pidfile

Je cherche un moyen de tuer tous les processus avec un nom donné qui fonctionnent depuis plus de X fois. J'engendre de nombreuses instances de cet exécutable particulier, et parfois il va dans un mauvais état et s'exécute pour toujours, prenant beaucoup de CPU.

J'utilise déjà monit, mais je ne sais pas comment rechercher un processus sans fichier pid. La règle serait quelque chose comme ceci:

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

Comment exprimeriez-vous cela en monit?

39
Parand

Dans monit, vous pouvez utiliser une chaîne correspondante pour les processus qui n'ont pas de PID. En utilisant l'exemple d'un processus nommé "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

Peut-être que si vous vérifiez si la charge du processeur est à un certain niveau pendant 10 cycles de surveillance (de 30 secondes chacun), puis redémarrez ou tuez, cela pourrait être une option. Ou vous pouvez utiliser test d'horodatage de monit sur un fichier lié au processus.

83
ewwhite

Il n'y a pas d'outil prêt à l'emploi avec cette fonctionnalité. Supposons que vous vouliez tuer les scripts php-cgi, qui s'exécutent plus d'une minute. Faites ceci:

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 sélectionnera les processus par leur nom, ps -o pid,time imprime le runtime pour chaque pid, puis analyse la ligne, en extrait le temps et imprime le pid si le temps se compare à celui défini. résultat passé à tuer.

5
datacompboy

J'ai résolu ce problème exact avec ps-watcher et j'ai écrit à ce sujet sur linux.com il y a quelques années. ps-watcher vous permet de surveiller les processus et de les tuer en fonction du temps d'exécution cumulé. Voici la configuration pertinente de ps-watcher, en supposant que votre processus est nommé '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

La clé est la ligne

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

qui dit 'si le temps de processus accumulé est> 1 heure ET je ne suis pas le processus parent, redémarrez-moi.

Donc, je me rends compte que la réponse n'utilise pas monit, mais cela fonctionne. ps-watcher est léger et simple à configurer, il n'y a donc aucun mal à l'exécuter en plus de votre configuration de monit.

3
Phil Hollenback

Monit peut le faire à partir de la version 5.4:

if uptime > 3 days then restart

Voir: le fichier CHANGES du projet

3
David Radcliffe

Vous pouvez l'intégrer à monit comme une instruction exec.

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