Se você tem sido um administrador por qualquer período de tempo, certamente descobriu situações em que um servidor aumenta o uso da CPU ou a utilização da memória e / ou os níveis de carga. Correr `top` nem sempre lhe dará a resposta. Então, como você encontra esses processos sorrateiros que estão destruindo seus recursos do sistema para poder matá-los?
O script a seguir pode ajudar. Ele foi escrito para um servidor da Web, assim, algumas partes dele estão especificamente procurando por processos httpd e algumas partes que lidam com o MySQL. Dependendo da implantação do seu servidor, simplesmente comente / exclua essas seções e adicione outras. Deve ser usado para um ponto de partida.
Pré-requisitos para esta versão do script são alguns freewares liberados sob a Licença Pública Geral GNU chamada mytop (disponível em https://jeremy.zawodny.com/mysql/mytop/) que é uma ferramenta fantástica para verificar como o MySQL está executando. Está ficando velho, mas ainda funciona muito bem para nossos propósitos aqui. Adicionalmente, eu uso o mutt como o mailer - você pode querer mudar o script para simplesmente usar o linux construído no utilitário `mail`. Eu corro via cron a cada hora; ajuste como achar melhor. Ah - e este script precisa ser executado como root, já que lê algumas áreas protegidas do servidor.
Então vamos começar, vamos?
Primeiro, defina suas variáveis de script:
#!/bin/bash # # Script to check system load average levels to try to determine # what processes are taking it overly high… # # 07Jul2010 tjones # # set environment dt=`date +%d%b%Y-%X` # Obviously, change the following directories to where your log files actually are kept tmpfile='/tmp/checkSystemLoad.tmp' logfile='/tmp/checkSystemLoad.log' msgLog='/var/log/messages' mysqlLog='/var/log/mysqld.log' # the first mailstop is standard email for reports. Second one is for cell phone (with a pared down report) mailstop='[email protected]' mailstop1='[email protected]' machine=`hostname` # The following three are for mytop use - use a db user that has decent rights dbusr='username' dbpw='password' db='yourdatabasename' # The following is the load level to check on - 10 is really high, so you might want to lower it. levelToCheck=10
Em seguida, verifique seu nível de carga para ver se o script deve continuar:
# Set variables from system: loadLevel=`cat /proc/loadavg | awk '{print $1}'` loadLevel=$( printf '%0.f' $loadLevel )
# if the load level is greater than you want, start the script process. Otherwise, exit 0
if [ $loadLevel -gt $levelToCheck ]; then echo '' > $tmpfile echo '**************************************' >>$tmpfile echo 'Date: $dt ' >>$tmpfile echo 'Check System Load & Processes ' >>$tmpfile echo '**************************************' >>$tmpfile
E continue com as verificações, escrevendo os resultados no arquivo temporário. Adicione ou exclua itens aqui, quando aplicável à sua situação:
# Get more variables from system: httpdProcesses=`ps -def | grep httpd | grep -v grep | wc -l`
# Show current load level: echo 'Load Level Is: $loadLevel' >>$tmpfile echo '*************************************************' >>$tmpfile
# Show number of httpd processes now running (not including children): echo 'Number of httpd processes now: $httpdProcesses' >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Show process list: echo 'Processes now running:' >>$tmpfile ps f -ef >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Show current MySQL info: echo 'Results from mytop:' >>$tmpfile /usr/bin/mytop -u $dbusr -p $dbpw -b -d $db >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
Observe com o comando top, estamos gravando em dois arquivos temporários. Uma é a mensagem muito menor para o celular. Se você não deseja a urgência dos alertas de celular às três da manhã, pode removê-lo (e retirar a segunda rotina de correspondência posteriormente no script).
# Show current top: echo 'top now shows:' >>$tmpfile echo 'top now shows:' >>$topfile /usr/bin/top -b -n1 >>$tmpfile /usr/bin/top -b -n1 >>$topfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
Mais cheques:
# Show current connections: echo 'netstat now shows:' >>$tmpfile /bin/netstat -p >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Check disk space echo 'disk space:' >>$tmpfile /bin/df -k >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
Em seguida, grave o conteúdo do arquivo temporário em um arquivo de log mais permanente e envie os resultados por e-mail para as partes apropriadas. A segunda correspondência é os resultados simplificados que consistem simplesmente no padrão out of `top`:
# Send results to log file: /bin/cat $tmpfile >>$logfile
# And email results to sysadmin: /usr/bin/mutt -s '$machine has a high load level! - $dt' -a $mysqlLog -a $msgLog $mailstop <$tmpfile /usr/bin/mutt -s '$machine has a high load level! - $dt' $mailstop1 <$topfile echo '**************************************' >>$logfile
E então algumas tarefas domésticas e sair:
# And then remove the temp file: rm $tmpfile rm $topfile fi
# exit 0
Espero que isso ajude alguém lá fora. O script totalmente montado é:
#!/bin/bash # # Script to check system load average levels to try to determine what processes are # taking it overly high… # # set environment dt=`date +%d%b%Y-%X` # Obviously, change the following directories to where your log files actually are kept tmpfile='/tmp/checkSystemLoad.tmp' logfile='/tmp/checkSystemLoad.log' msgLog='/var/log/messages' mysqlLog='/var/log/mysqld.log' # the first mailstop is standard email for reports. Second one is for cell phone (with a pared down report) mailstop='[email protected]' mailstop1='[email protected]' machine=`hostname` # The following three are for mytop use - use a db user that has decent rights dbusr='username' dbpw='password' db='yourdatabasename' # The following is the load level to check on - 10 is really high, so you might want to lower it. levelToCheck=10 # Set variables from system: loadLevel=`cat /proc/loadavg | awk '{print $1}'` loadLevel=$( printf '%0.f' $loadLevel )
# if the load level is greater than you want, start the script process. Otherwise, exit 0
if [ $loadLevel -gt $levelToCheck ]; then echo '' > $tmpfile echo '**************************************' >>$tmpfile echo 'Date: $dt ' >>$tmpfile echo 'Check System Load & Processes ' >>$tmpfile echo '**************************************' >>$tmpfile
# Get more variables from system: httpdProcesses=`ps -def | grep httpd | grep -v grep | wc -l`
# Show current load level: echo 'Load Level Is: $loadLevel' >>$tmpfile echo '*************************************************' >>$tmpfile
# Show number of httpd processes now running (not including children): echo 'Number of httpd processes now: $httpdProcesses' >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Show process list: echo 'Processes now running:' >>$tmpfile ps f -ef >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Show current MySQL info: echo 'Results from mytop:' >>$tmpfile /usr/bin/mytop -u $dbusr -p $dbpw -b -d $db >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Show current top: echo 'top now shows:' >>$tmpfile echo 'top now shows:' >>$topfile /usr/bin/top -b -n1 >>$tmpfile /usr/bin/top -b -n1 >>$topfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Show current connections: echo 'netstat now shows:' >>$tmpfile /bin/netstat -p >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Check disk space echo 'disk space:' >>$tmpfile /bin/df -k >>$tmpfile echo '*************************************************' >>$tmpfile echo '' >>$tmpfile
# Send results to log file: /bin/cat $tmpfile >>$logfile
# And email results to sysadmin: /usr/bin/mutt -s '$machine has a high load level! - $dt' -a $mysqlLog -a $msgLog $mailstop <$tmpfile /usr/bin/mutt -s '$machine has a high load level! - $dt' $mailstop1 <$topfile echo '**************************************' >>$logfile
# And then remove the temp file: rm $tmpfile rm $topfile fi
# exit 0