Script de monitoramento
LidoNesta aula, você aprenderá a criar scripts de monitoramento de sistemas Linux, abrangendo checagem de serviços, uso de disco, envio de alertas por e-mail/log e agendamento com cron. O conteúdo inclui exemplos práticos, boas práticas e exercícios com respostas.
O monitoramento de sistemas é uma tarefa essencial para garantir a disponibilidade e a saúde de servidores e serviços. Scripts de monitoramento automatizam a verificação de recursos críticos, como serviços ativos, espaço em disco, uso de CPU e memória, e podem enviar alertas quando algo sai do esperado. Nesta aula, vamos explorar como criar scripts de monitoramento em Bash, desde a verificação de serviços até o agendamento dessas verificações.
Vamos abordar quatro áreas principais: checagem de serviços, uso de disco, alertas (por e-mail e log) e agendamento com cron. Ao final, você terá um repertório de técnicas para construir seus próprios scripts de monitoramento, com foco em robustez e boas práticas.
Checando serviços
Verificar se um serviço está ativo é uma das tarefas mais comuns em monitoramento. No Linux, podemos usar comandos como systemctl (para sistemas com systemd) ou service (para SysV init). O comando systemctl is-active retorna o status de um serviço de forma simples.
Em um script, podemos capturar o status e agir de acordo. Por exemplo, se um serviço crítico estiver inativo, podemos tentar reiniciá-lo ou enviar um alerta. Vamos ver um exemplo:
#!/bin/bash
# Script para verificar se o serviço nginx está ativo
SERVICE="nginx"
if systemctl is-active --quiet "$SERVICE"; then
echo "O serviço $SERVICE está ativo."
else
echo "O serviço $SERVICE está INATIVO!"
# Tenta reiniciar
systemctl restart "$SERVICE"
if systemctl is-active --quiet "$SERVICE"; then
echo "Serviço reiniciado com sucesso."
else
echo "Falha ao reiniciar o serviço."
fi
fi
Neste script, usamos systemctl is-active --quiet que não produz saída, apenas retorna o código de saída (0 se ativo, não-zero se inativo). Isso é útil para testes condicionais. Também podemos verificar múltiplos serviços em um loop, armazenando os nomes em um array.
#!/bin/bash
# Verifica múltiplos serviços
SERVICES=("nginx" "mysql" "docker")
for svc in "${SERVICES[@]}"; do
if systemctl is-active --quiet "$svc"; then
echo "$svc: ativo"
else
echo "$svc: INATIVO"
fi
done
É importante considerar que alguns serviços podem usar nomes diferentes do nome do processo. Verifique com systemctl list-units --type=service para ver os nomes corretos.
Uso de disco
O monitoramento do uso de disco é crucial para evitar que partições fiquem cheias, o que pode causar falhas em aplicações. O comando df mostra o uso de disco, e podemos analisar a saída para extrair a porcentagem de uso.
Um script pode verificar se a utilização de uma partição ultrapassou um limite (por exemplo, 80%) e então disparar um alerta. Vamos ver como fazer isso:
#!/bin/bash
# Verifica o uso de disco da raiz
THRESHOLD=80
CURRENT=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$CURRENT" -gt "$THRESHOLD" ]; then
echo "Alerta: uso de disco em / é ${CURRENT}% (limite: ${THRESHOLD}%)"
else
echo "Uso de disco em / é ${CURRENT}% (dentro do limite)."
fi
O comando df / mostra a linha da partição raiz, e com awk extraímos o quinto campo (a porcentagem), e com sed removemos o símbolo de porcentagem. Podemos generalizar para verificar várias partições, usando df -h e iterando sobre as linhas.
#!/bin/bash
# Verifica todas as partições montadas
THRESHOLD=80
df -h | tail -n +2 | while read line; do
# Extrai o ponto de montagem e a porcentagem
mount=$(echo "$line" | awk '{print $6}')
usage=$(echo "$line" | awk '{print $5}' | sed 's/%//')
if [ "$usage" -gt "$THRESHOLD" ]; then
echo "Alerta: partição $mount está com ${usage}% de uso."
fi
done
Neste exemplo, usamos tail -n +2 para pular o cabeçalho, e para cada linha extraímos o ponto de montagem (campo 6) e a porcentagem (campo 5). Note que a ordenação dos campos pode variar com as opções do df; verifique com df -h.
Uma alternativa mais robusta é usar o comando findmnt ou ler o arquivo /proc/mounts, mas para scripts simples, df é suficiente.
Alertas (e-mail/log)
Quando um problema é detectado, é essencial notificar o administrador. Duas formas comuns são enviar e-mail e registrar em arquivos de log. O envio de e-mail pode ser feito com o comando mail ou sendmail, mas é necessário um servidor de e-mail configurado ou um serviço externo. Para esta aula, usaremos o comando mail (pacote mailutils ou bsd-mailx).
Exemplo de envio de e-mail:
#!/bin/bash
# Envia um e-mail de alerta
EMAIL="admin@example.com"
SUBJECT="Alerta de monitoramento"
BODY="Problema detectado no servidor."
echo "$BODY" | mail -s "$SUBJECT" "$EMAIL"
Também podemos usar sendmail para maior controle, mas mail é mais simples.
Além do e-mail, registrar eventos em um arquivo de log é uma prática recomendada. Podemos usar logger para enviar mensagens ao syslog, ou simplesmente redirecionar a saída para um arquivo. Exemplo:
#!/bin/bash
# Registra alerta em arquivo de log
LOG_FILE="/var/log/monitor.log"
echo "$(date '+%Y-%m-%d %H:%M:%S') - Alerta: uso de disco acima do limite" >> "$LOG_FILE"
Em scripts de monitoramento, é comum combinar e-mail e log. Vamos criar uma função para enviar alertas que registra no log e envia e-mail:
#!/bin/bash
LOG_FILE="/var/log/monitor.log"
EMAIL="admin@example.com"
send_alert() {
local MESSAGE="$1"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $MESSAGE" >> "$LOG_FILE"
echo "$MESSAGE" | mail -s "[Monitor] Alerta" "$EMAIL"
}
# Uso
send_alert "Disco cheio!"
Lembre-se de que o comando mail pode exigir configurações adicionais, como um relay. Em servidores de produção, é comum usar um serviço de e-mail transacional ou um script de envio via API.
Agendamento
Para que os scripts de monitoramento sejam executados periodicamente, usamos o cron, o agendador de tarefas do Linux. O cron lê arquivos de configuração (crontab) e executa comandos nos horários especificados.
Para editar o crontab do usuário atual, use crontab -e. A sintaxe básica é: minuto hora dia-do-mês mês dia-da-semana comando. Por exemplo, para executar o script a cada 5 minutos:
*/5 * * * * /caminho/para/script.sh
Se o script precisar de permissões de root, edite o crontab do root (sudo crontab -e).
Um cuidado importante: scripts executados pelo cron não têm o mesmo ambiente que o shell interativo. Por isso, é recomendável usar caminhos absolutos para comandos e definir variáveis de ambiente, como PATH, no início do script.
Exemplo de crontab para monitorar a cada 10 minutos e enviar alertas:
# Edite com crontab -e
*/10 * * * * /usr/local/bin/monitor.sh
Também podemos usar systemd timers como uma alternativa mais moderna, mas o cron ainda é amplamente utilizado. Para agendar tarefas mais complexas, como a cada hora em um dia específico, consulte a documentação do cron.
Uma dica: teste o script manualmente antes de agendar, e verifique os logs do cron (/var/log/syslog ou /var/log/cron) para garantir que está sendo executado.
Boas práticas
Ao criar scripts de monitoramento, siga estas boas práticas:
- Use caminhos absolutos para comandos e arquivos, especialmente quando executado pelo cron.
- Defina variáveis de ambiente no início do script, como
PATH. - Trate erros com
set -eou verificação de códigos de saída. - Use funções para organizar o código e evitar repetição.
- Registre todas as ações em logs para facilitar a depuração.
- Teste exaustivamente antes de colocar em produção.
Referências
- Bash Reference Manual
- df(1) - Linux manual page
- systemctl(1) - Linux manual page
- crontab(5) - Linux manual page
- logger(1) - Linux manual page
- mail(1) - Linux manual page
Exercícios
- Exercício 1: Escreva um script que verifique se o serviço
sshdestá ativo e, se não estiver, tente iniciá-lo e exiba uma mensagem de sucesso ou falha. - Exercício 2: Crie um script que monitore o uso de disco da partição
/home, alertando se a utilização for maior que 90%. Use o comandodfeawk. - Exercício 3: Escreva um script que envie um e-mail de alerta e registre em um log quando o uso de memória ultrapassar 80%. Use o comando
freepara obter o uso. - Exercício 4: Agende o script do Exercício 2 para executar a cada 5 minutos usando cron. Mostre a linha do crontab.
- Exercício 5: Crie um script que verifique se uma lista de serviços (por exemplo, nginx, mysql, docker) está ativa e envie um alerta por e-mail para cada serviço inativo. Use um loop.
#!/bin/bash
SERVICE="sshd"
if systemctl is-active --quiet "$SERVICE"; then
echo "O serviço $SERVICE já está ativo."
else
echo "O serviço $SERVICE está inativo. Tentando iniciar..."
systemctl start "$SERVICE"
if systemctl is-active --quiet "$SERVICE"; then
echo "Serviço iniciado com sucesso."
else
echo "Falha ao iniciar o serviço."
fi
fi
#!/bin/bash
THRESHOLD=90
CURRENT=$(df /home | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$CURRENT" -gt "$THRESHOLD" ]; then
echo "ALERTA: Uso de disco em /home é ${CURRENT}% (limite: ${THRESHOLD}%)"
else
echo "Uso de disco em /home é ${CURRENT}% (dentro do limite)."
fi
#!/bin/bash
THRESHOLD=80
MEM_USAGE=$(free | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')
if [ "$MEM_USAGE" -gt "$THRESHOLD" ]; then
MESSAGE="Uso de memória em ${MEM_USAGE}%"
echo "$(date '+%Y-%m-%d %H:%M:%S') - $MESSAGE" >> /var/log/monitor.log
echo "$MESSAGE" | mail -s "[Monitor] Alerta de memória" admin@example.com
fi
*/5 * * * * /caminho/para/script.sh
#!/bin/bash
SERVICES=("nginx" "mysql" "docker")
EMAIL="admin@example.com"
for svc in "${SERVICES[@]}"; do
if ! systemctl is-active --quiet "$svc"; then
echo "O serviço $svc está inativo." | mail -s "Alerta: serviço $svc" "$EMAIL"
fi
done