monit: vérifier le processus sans pidfile

37

Je cherche un moyen de supprimer tous les processus portant le même nom et fonctionnant depuis plus de X fois. Je génère beaucoup d'exemples de cet exécutable particulier, et parfois, il entre dans un mauvais état et fonctionne pour toujours, prenant beaucoup de ressources processeur.

J'utilise déjà monit, mais je ne sais pas comment vérifier 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 in monit?

Parand
la source
( vous devriez marquer ici une réponse )
ewwhite

Réponses:

80

Dans monit, vous pouvez utiliser une chaîne de correspondance pour les processus sans 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. Vous pouvez également utiliser les tests d’horodatage de monit sur un fichier lié au processus.

ewwhite
la source
1
Attention: cela ne fonctionnera pas s'il y a plusieurs processus
ruX
1
vous pouvez utiliser une expression rationnelle: matchin "otherstuff. * myprocessname"
user174962
@ruX: que se passe-t-il si plusieurs processus liés concordent? Comment peuvent-ils manipulés?
kontextify
Ça prend le premier match.
ewwhite
5

Il n'y a pas d'outil prêt à l'emploi avec cette fonctionnalité. Supposons que vous souhaitiez supprimer les scripts php-cgi, dont la durée est supérieure à minute. Faire 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

pgrepsélectionnera les processus par leur nom, ps -o pid,timeimprimera le runtime pour chaque pid, analysera la ligne, en extraira l'heure et imprimera le pid si le temps est comparable à celui défini. résultat passé à tuer.

datacompboy
la source
le processus exécuté depuis très longtemps prend un temps d'exécution étrange (62-13: 53: 05), le temps d'exécution de l'analyse rationnelle doit donc être ([-0-9] +: [0-9] +: [0-9] + ) - regardez le signe moins au début de l’expression.
Andrej
3

J'ai résolu ce problème avec ps-watcher et en ai parlé 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 accumulé. Voici la configuration appropriée de ps-watcher, en supposant que votre processus s'appelle '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 que je ne suis pas le processus parent, redémarrez-moi.

Donc, je me rends compte que la réponse n’utilise pas monit, mais que ça marche. ps-watcher est léger et simple à configurer. Par conséquent, rien ne vous empêche de le faire en plus de votre configuration monit.

Phil Hollenback
la source
3

Monit peut le faire à partir de la version 5.4:

if uptime > 3 days then restart

Voir: le fichier CHANGES du projet

David Radcliffe
la source
0

Vous pouvez utiliser cela comme une instruction exec.

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