Use monit para monitorar subprocessos do apache2

4

No momento, estou usando o Monit para monitorar o Apache e reiniciá-lo se o uso de memória for muito alto. No entanto, eu também gostaria de poder monitorar os subprocessos apache2 individuais que são gerados e matar qualquer subprocesso cujo uso de memória seja muito alto em um período de alguns minutos. Como posso fazer isso?

    
por Matt White 17.07.2012 / 17:59

2 respostas

3

A documentação do Monit sugere que você possa monitorar de forma nativa a memória total usada pelo Apahce e seus processos filhos, e não qualquer processo filho individual.

No entanto, você pode verificar o status de retorno de um script usando o check program test:

link

Então, você pode fazer algo parecido com um script de verificação:

#/bin/bash
threshold=10000 # 10MB

for childmem in $(ps h orss p $(pgrep -P $(cat /var/run/httpd.pid)))
do
  if [ $childmem -gt $threshold ]; then
     exit 1
  fi
done
exit 0

Se esse script for /usr/local/bin/check_apache_children.sh , você poderá fazer algo como:

 check program myscript with path "/usr/local/bin/check_apache_children.sh"
       if status != 0 then exec "/usr/local/bin/kill_apache_children.sh"

O script kill provavelmente será parecido com o script de verificação, mas com um kill no PID em vez de uma saída.

Os scripts são, obviamente, ilustrativos e devem ser modificados para o seu ambiente.

    
por 17.07.2012 / 18:40
2

Aceitei a resposta do cjc acima, mas queria postar exatamente como usei a sugestão dele para resolver esse problema. Note que você precisará usar pelo menos o Monit 5.3 para usar o "programa de verificação" do Monit. Eu estou executando o Debian.

/ usr / local / bin / monit_check_apache2_children:

#!/usr/bin/env bash

log_file=/path/to/monit_check_apache2_children.log
mem_limit=6
kill_after_minutes=5

exit_code=0
date_nice=$(date +'%Y-%m-%d %H:%M:%S')
date_seconds=$(date +'%s')
apache_children=$(ps h -o pid,%mem p $(pgrep -P $(cat /var/run/apache2.pid)) | sed 's/^ *//' | tr ' ' ',' | sed 's/,,/,/g')

for apache_child in $apache_children; do
  pid='echo $apache_child | awk -F, '{ print $1 }''
  mem='echo $apache_child | awk -F, '{ print $2 }''
  mem_rounded='echo $apache_child | awk -F, '{ printf("%d\n", $2 + 0.5) }''

  if [ $mem_rounded -ge $mem_limit ]; then
    log_entry_count=$(cat $log_file | grep -v 'KILLED' | grep " $pid; " | wc -l)
    log_entry_time=$(cat $log_file | grep -v 'KILLED' | grep " $pid; " | tail -$kill_after_minutes | head -1 | awk '{ print $3 }')

    if [ "$1" != "kill" ]; then
      echo "$date_nice $date_seconds Process: $pid; Memory Usage: $mem" >> $log_file
    fi

    if [ $((date_seconds - log_entry_time)) -le $(((kill_after_minutes * 60) + 30)) ] && [ $log_entry_count -ge $kill_after_minutes ]; then
      if [ "$1" = "kill" ]; then
        kill -9 $pid
        echo "$date_nice $date_seconds ***** KILLED APACHE2 PROCESS: $pid; MEMORY USAGE: $mem" >> $log_file
      else
        exit_code=1
      fi
    fi
  fi
done

exit $exit_code

/ etc / monitrc:

...
check program apache2_children
  with path "/usr/local/bin/monit_check_apache2_children"
  if status != 0 then exec "/usr/local/bin/monit_check_apache2_children kill"
...
    
por 17.07.2012 / 22:48