monit: verifica processo sem pidfile

35

Estou procurando uma maneira de eliminar todos os processos com um determinado nome que estão sendo executados por mais de X período de tempo. Eu gero muitas instâncias deste executável particular, e às vezes ele entra em um estado ruim e é executado para sempre, ocupando muito cpu.

Eu já estou usando o monit, mas não sei como verificar um processo sem um arquivo pid. A regra seria algo assim:

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

Como você expressaria isso em monit?

    
por Parand 16.05.2011 / 20:37

5 respostas

76

Em monit, você pode usar uma string correspondente para processos que não possuem um PID. Usando o exemplo de um processo chamado "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

Talvez, se você verificar se a carga da CPU está em um determinado nível para 10 ciclos de monitoramento (de 30 segundos cada), reinicie ou mate, isso pode ser uma opção. Ou você pode usar o testes de carimbo de data / hora da monit em um arquivo relacionado ao processo.

    
por 30.06.2011 / 03:12
5

Não há ferramentas prontas para usar com essa funcionalidade. Vamos supor que você queira matar scripts php-cgi, que são mais longos que minutos. Faça isso:

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 selecionará os processos pelo nome, ps -o pid,time imprime tempo de execução para cada pid e, em seguida, analisa a linha, extrai o tempo dela e imprime pid se o tempo se comparar com o definido. resultado passado para matar.

    
por 17.05.2011 / 03:25
3

Eu resolvi esse problema exato com o ps-watcher e escrevi sobre ele em linux.com alguns anos atrás . O ps-watcher permite monitorar processos e eliminá-los com base no tempo de execução acumulado. Aqui está a configuração relevante do ps-watcher, assumindo que seu processo é chamado '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

A chave é a linha

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

que diz "se o tempo de processo acumulado for > 1 hora E eu não sou o processo pai, me reinicie.

Então, percebo que a resposta não usa monit, mas funciona. O ps-watcher é leve e simples de configurar, portanto, não há problema em executá-lo além da sua configuração de monit.

    
por 17.05.2011 / 05:17
3

Monit pode fazer isso a partir da versão 5.4:

if uptime > 3 days then restart

Veja: o arquivo CHANGES do projeto

    
por 26.02.2013 / 20:22
0

Você poderia trabalhar isso em monit como uma declaração exec.

    if [[ "$(uname)" = "Linux" ]];then killall --older-than 2m someprocessname;fi
    
por 29.05.2012 / 03:06