Monit: comprobar el proceso sin pidfile

37

Estoy buscando una forma de eliminar todos los procesos con un nombre de pila que se hayan estado ejecutando durante más de X veces. Engendro muchas instancias de este ejecutable en particular, y a veces entra en un mal estado y se ejecuta para siempre, ocupando mucha CPU.

Ya estoy usando monit, pero no sé cómo verificar un proceso sin un archivo pid. La regla sería algo como esto:

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

¿Cómo expresarías esto en monit?

Desfile
fuente
( debe marcar una respuesta aquí )
ewwhite

Respuestas:

80

En monit, puede usar una cadena coincidente para procesos que no tienen un PID. Usando el ejemplo de un proceso llamado "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

Tal vez si verifica si la carga de la CPU está en un cierto nivel durante 10 ciclos de monitoreo (de 30 segundos cada uno), luego reiniciar o matar, esa podría ser una opción. O puede usar la prueba de marca de tiempo de monit en un archivo relacionado con el proceso.

ewwhite
fuente
1
Tenga cuidado: no funcionará, hay más de un proceso
ruX
1
puede usar una expresión regular: matchin "otherstuff. * myprocessname"
user174962
@ruX: ¿qué sucede si coinciden varios procesos relacionados? ¿Cómo se pueden manejar?
kontextify
Se necesita el primer partido.
ewwhite
5

No hay una herramienta lista para usar con esa funcionalidad. Supongamos que quiere matar los scripts php-cgi, que duran más de un minuto. Hacer esto:

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

pgrepseleccionará los procesos por nombre, ps -o pid,timeimprime el tiempo de ejecución para cada pid y luego analiza la línea, extrae el tiempo e imprime pid si el tiempo se compara con el definido. resultado pasado a matar.

datacompboy
fuente
el proceso runnig por muy largo tiempo se extraña de tiempo de ejecución (62-13: 53: 05), por lo que la expresión regular análisis de tiempo de ejecución debe ser ([-0-9] +: [0-9] +: [0-9] + ) - mira el signo menos al comienzo de la expresión.
andrej
3

Resolví este problema exacto con ps-watcher y escribí sobre ello en linux.com hace unos años. ps-watcher le permite monitorear procesos y eliminarlos en función del tiempo de ejecución acumulado. Aquí está la configuración relevante de ps-watcher, suponiendo que su proceso se llame '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 clave es la linea

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

que dice 'si el tiempo de proceso acumulado es> 1 hora Y no soy el proceso padre, reiníciame.

Entonces, me doy cuenta de que la respuesta no usa monit, pero funciona. ps-watcher es liviano y fácil de configurar, por lo que no es perjudicial ejecutarlo además de la configuración de su monitor.

Phil Hollenback
fuente
0

Podría trabajar esto en monit como una declaración ejecutiva.

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