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?
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.
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.
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.
Monit peut le faire à partir de la version 5.4:
if uptime > 3 days then restart
Vous pouvez l'intégrer à monit comme une instruction exec.
if [[ "$(uname)" = "Linux" ]];then killall --older-than 2m someprocessname;fi