Monitor em tempo real de% iowait

2

Eu sou novo em scripts e sei que a pergunta abaixo é muito simples, mas não está conseguindo nada.

O comando sar fornece a saída abaixo,

root@virt01:~# sar 1 1

Linux 3.19.0-42-generic (virt01.ubuntu.com)     13/02/16        _x86_64_        (1 CPU)

12:19:55        CPU     %user     %nice   %system   %iowait    %steal     
%idle

12:19:56        all      0.00      0.00      0.00      0.00      0.00    
100.00
Average:        all      0.00      0.00      0.00      0.00      0.00    100.00
root@virt01:~#

Só quero verificar como determinado valor, por exemplo:% iowait e enviar alerta de email se exceder 50.

Se você puder ajudar, ficaria grato.

Obrigado.

    
por Kumar Raj 09.02.2018 / 02:10

1 resposta

1

Começando com o comando sar 1 1 :

# sar 1 1
Linux 4.14.14 (sys.local)   02/08/2018  _x86_64_    (4 CPU)
09:38:01 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
09:38:02 PM     all      5.74      0.00      1.50      0.00      0.00     92.77
Average:        all      5.74      0.00      1.50      0.00      0.00     92.77

Queremos a coluna% iowait. Uma string comum para corresponder a regex em cada linha é all em CPU , portanto:

# sar 1 1 | awk '/all|iowait/{print $7}'
%iowait
0.00
0.00

Nesse caso, adicionamos iowait à regex para confirmar que obtivemos a coluna correta, $7 . (Veja man awk para mais detalhes sobre o uso do awk.) Nosso próximo passo é salvar esses valores para uso em nosso script:

# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) )

Esta sintaxe var=() é para uma matriz. Veja man bash para detalhes. Podemos referenciar esses valores com $ {iowait [1]}, então agora estamos preparados para um loop sobre os dois valores:

# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; for I in ${iowait[*]} ; do \
   echo $I ; \
   done 
0.25
0.00

Ótimo, quase lá, não podemos comparar esses valores com um condicional. Isso levará algum esforço extra, porque o bash prefere comparar inteiros em vez de floats. Poderíamos multiplicar por 100 antes da comparação, mas é mais fácil usar um atalho bash para descartar os decimais antes da comparação. Para obter 12 de 12,34 na variável $I , usaremos a sintaxe $ {I %%. *}. Isso remove o sufixo correspondente da variável I e o regex .* corresponde a qualquer coisa, portanto, tudo após o decimal. -lt no bash funcionará dentro de um condicional: if [ ]; then something; fi Tudo isso é descrito em detalhes em man bash para referência.

# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; \
  for I in ${iowait[*]} ; do \
      if [ ${I%%.*} -lt 2 ] ; then \
         echo "$I < 2" ; \
      fi ; \
  done
0.00 < 2
0.00 < 2

Uma adição final antes de enviarmos nosso e-mail, vamos adicionar um registro de data e hora específico e ver o que está sendo executado durante esse IO alto:

# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; \
  for I in ${iowait[*]} ; do \
      if [ ${I%%.*} -lt 2 ] ; then \
         echo "$(date -Is): iowait = $I\n $(ps)" ; \
      fi ; \
  done 
2018-02-08T22:09:21-05:00: iowait = 0.25
   PID TTY          TIME CMD
 3431 pts/1    00:00:00 zsh
28148 pts/1    00:00:00 ps
2018-02-08T22:09:21-05:00: iowait = 0.00
   PID TTY          TIME CMD
 3431 pts/1    00:00:00 zsh
28150 pts/1    00:00:00 ps

É claro que melhores opções de ps, como ps eaf ou ps auxfw , podem ser usadas como você preferir para mais detalhes. Não, para atingir efetivamente a tarefa (comparando -gt 50 ) e enviar o email direcionando nossa saída para mailx :

# iowait=( $( sar 1 1 | awk '/all/{print $7}' ) ) ; \
  for I in ${iowait[*]} ; do \
     if [ ${I%%.*} -gt 50 ] ; then echo "$(date -Is): iowait = $I\n $(ps)" |
        mailx -s "hi iowait" root ; \
     fi  ; \
  done

Espero que isso responda à sua pergunta e demonstre como alguém pode construir o que deseja, quebrando o problema passo a passo, aproveitando a filosofia unix, muitas ferramentas e páginas de manual.

    
por 09.02.2018 / 04:22

Tags