Criando alertas com Prometheus e Alertmanager

Aprenda a criar alertas personalizados das suas métricas utilizando o Prometheus e Alertmanager.

Criando alertas com Prometheus e Alertmanager

Fala pessoal tudo beleza?

Se você caiu nesse artigo pela primeira vez, fique sabendo que essa é uma série de artigos onde descrevo como montar uma stack de monitoramento usando o Grafana e Prometheus com o docker e docker-compose.

Artigos da série

  1. Monitorando seus servidores com Grafana e Prometheus
  2. Instalação e configuração do Node Exporter em servidores Linux
  3. Criando alertas com Prometheus e Alertmanager (Você está aqui!)
  4. Configure e gerencie alertas no Grafana: Maximize a eficiência do monitoramento

Neste artigo, parte 3, irei criar alertas costumizados para suas métricas no Prometheus e Alertmanager, que será responsável em disparar o evento para um e-mail.

Pré requisitos

  • Ter uma instância do Prometheus em execução.
  • Ter acompanhado os artigos anteriores onde subimos uma stack do Grafana e Prometheus.

Instalando o Alertmanager

O Alertmanager é um software que lida com alertas enviados por aplicativos clientes, como o servidor Prometheus. Ele é responsável em gerenciar esses alertas recebidos e encaminhar para algum cliente que esteja pré configurado, como um e-mail.

Com ele também é possível configurar o modo de silenciamento, ou seja, silenciar algum alerta já esperado por algumas horas ou apenas para o fim de semana.

Para subir uma instância do Alertmanager, iremos usar o docker. Para isso, utilize a stack que estamos criando nessa série de artigo e abra o arquivo docker-compose.yaml. Você pode encontrar no meu Github.

Para nosso exemplo de hoje com o Alertmanager, iremos usar o Node Exporter em uma imagem docker. No arquivo docker-comose.yaml já existe um serviço para ele, que está comentado. Descomente o bloco referente ao node_exporter e adicione logo abaixo o bloco do Alertmanager:

# Arquivo: docker-compose.yaml
services:

  # ...services

  # Exemplo de usar o exporter com o Docker ao invés do binário
  node_exporter:
    image: quay.io/prometheus/node-exporter:latest
    container_name: node_exporter
    command:
      - '--path.rootfs=/host'
    pid: host
    restart: always
    volumes:
      - '/:/host:ro,rslave'
    networks:
      - monitoring

  alertmanager:
    image: prom/alertmanager:v0.25.0
    container_name: alertmanager
    restart: always
    volumes:
      - ./alertmanager/:/etc/alertmanager/
    command:
      - '--config.file=/etc/alertmanager/config.yaml'
      - '--storage.path=/alertmanager'
    ports:
      - 9093:9093
    networks:
      - monitoring

Explicando algumas linhas importantes do Alertmanager no arquivo docker-compose.yaml:

  1. No serviço alertmanager, informamos a versão do Alertmanager que será utilizada que é a 0.25.0 (a mais recente na data desse artigo).
  2. Criamos um volume para mapear um arquivo de configuração para o Alertmanager, que ao iniciar o serviço essa configuração será aplicada.
  3. Em command, estamos passando dois parâmetros para o Alertmanager, o primeiro --config.file informamos que o arquivo de configuração deve ser lido no diretório /etc/alertmanager/config.yaml e o segundo --storage.path informamos que o local de armazenamento dos dados serão armazenados no próprio host em /alertmanager.
  4. Em ports estamos expondo a porta 9093 do host para a porta 9093 do container.
  5. Em networks informamos ao docker-compose que iremos utilizar uma rede já criada por nós, que no caso é a rede monitoring.

Agora vamos subir os containers na nossa stack. No diretório raiz do projeto, execute o comando do docker compose para subir todas as instâncias de containers:

$ docker-compose up -d

Verifique se todos os containers estão em execução:

$ docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
alertmanager        "/bin/alertmanager -…"   alertmanager        running             0.0.0.0:9093->9093/tcp, :::9093->9093/tcp
grafana             "/run.sh"                grafana             running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
node_exporter       "/bin/node_exporter …"   node_exporter       running             9100/tcp
prometheus          "/bin/prometheus --c…"   prometheus          running             0.0.0.0:9090->9090/tcp, :::9090->9090/tcp

Agora o Alertmanager está running e está acessível na porta 9093. Acesse o navegador com o endereço localhost:9093 e confirme se o Alertmanager irá carregar.

Tela inicial Alertmanager
Tela inicial Alertmanager

Integrando Alertmanager com Prometheus

Já temos nossa instância do Alertmanager em execução, precisamos agora configurar o Prometheus para qualquer evento de alerta seja enviado ao Alertmanager e ele ser responsável em disparar para um cliente.

Abra o arquivo de configuração do Prometheus que está em prometheus/prometheus.yaml. Adicione a seguinte entrada no final do arquivo referenciando ao Alertmanager:

# ...

alerting:
  alertmanager:
  - scheme: http
    static_configs:
    - targets: 
      - 'alertmanager:9093'

prometheus/prometheus.yaml

Nesse bloco de código, informamos ao Prometheus que existe agora um cliente de alerta. Na sessão alerting criamos um, chamado alertmanager. Informamos que o Alertmanager está rodando no protocolo http e no host alertmanager:9093.

Vamos validar se o Prometheus reconheceu essa nossa configuração. Para isso reinicie o serviço do Prometheus com o comando:

$ docker-compose restart prometheus

Abra o Prometheus no seu navegador em localhost:9090 e navegue no menu Status -> Runtime & Build Information. Certifique que na sessão Alertmanagers, agora há um endpoint apontando para a instância do Alertmanager.

Com isso já temos a integração entre os dois serviços. Agora é necessário criar os alertas no Prometheus e quando acionado será enviado um evento de alerta para o Alertmanager.

Criando regras de alertas no Prometheus

Agora que já temos nossa instância em execução, vamos criar as regras de alertas no Prometheus. Para isso vamos criar um arquivo chamado alert.rules no diretório do prometheus.

Adicone o seguinte conteúdo nesse arquivo:

groups:

# Grupo de alertas: hosts
- name: hosts
  rules:
  - alert: Uptime
    expr: up == 0
    for: 15s
    labels:
      severity: critical
    annotations:
      summary: "O servidor {{ $labels.alias }} está offline!"
      description: "O servidor {{ $labels.alias }} parou de responder."

  - alert: Uso de CPU
    expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[2m])) by(instance) * 100) > 80
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: Consumo alto de CPU (instance {{ $labels.instance }})
      description: "O servidor {{ $labels.alias }} está com o consumo de CPU acima de 80%\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"

prometheus/alert.rules

Foram criadas duas regras de alertas, onde o primeiro é o Uptime, que verifica se a instância está no ar e a segunda verifica o uso de CPU se está acima de 80% em um período de 2 minutos.

Lembre-se de validar as regras para seu ambiente antes de usar em produção.

Após criarmos o arquivo de regras, devemos informar ao Prometheus que ele deve carregar esse arquivo a aplicar suas configurações. Para isso abra novamente o arquivo prometheus/prometheus.yaml e adicione no inicio do arquivo o seguinte trecho:

# Arquivo: prometheus/prometheus.yaml
global:
  scrape_interval: 15s

# Carrega arquivo de regras de alertas
rule_files:
  - "alert.rules"

Nesse arquivo adicionamos a sessão de regras rules_files, que indica que o Prometheus deve carregar o arquivo correspondente que contém as regras de alertas.

Agora reinicie o Prometheus para aplicar as configurações:

$ docker-compose restart prometheus

Para validarmos todo esse processo, vamos abrir o Prometheus no navegador e acessar o menu Status -> Rules. Você verá a seguinte tela com as regras criadas.

Regras de alertas para Prometheus
Regras de alertas para Prometheus

Acesse também o menu Alerts, você verá as regras criadas e o status de cada uma.

Status inativo de alerta do Prometheus
Prometheus rules status Inactive

Nessa tela, é possível acompanhar o status de cada evento de alerta. Podemos ver os status:

  • Inactive: Esse status significa que não há nenhum evento de alerta que possa ser acionado, ou seja, está tudo bem!
  • Pending: Quando um alerta entra nesse status, quer dizer que alguma regra definida foi acionada, ficará nesse status pelo tempo determinado no arquivo de regras.
  • Firing: Após o status de Pending, o status Firing entra em ação, após um evento ficar em espera por alguns segundos seu status muda para Firing e automaticamente é dispardo um alerta para o Alertmanager.

Configurando Alertmanager com SMTP

Agora é hora de configurar o Alertmanager com as informações de credenciais de e-mail usando o SMTP. Para isso, crie um arquivo config.yaml no diretório alertmanager. Cole o seguinte conteúdo no arquivo:

# Arquivo: alertmanager/config.yaml
global:
  smtp_smarthost: smtp.email.com:587
  smtp_from: [email protected]
  smtp_auth_username: [email protected]
  smtp_auth_password: suaSenhaAqui

route:
  group_by: ['alertname']
  group_interval: 5m
  group_wait: 30s
  receiver: 'email'
  repeat_interval: 3h

receivers:

  - name: 'email'
    email_configs:
    - to: [email protected]
      send_resolved: true

Você deve adicionar as suas configurações SMTP do seu provedor de e-mail.

Basicamente neste arquivo eu digo ao Alertmanager que ele deverá enviar um e-mail para receivers.name.email_configs: [email protected] após 30 segundos route.group_wait que ele receber o alerta.

Em receivers.name.email_configs.send_resolved: true informo que após a resolução de um incidente, o Alertmanager deverá enviar outro e-mail alertando que o incidente foi resolvido.

Defino o remetente padrão em route.receiver: email. Na sessão global informo as credenciais de e-mail SMTP.

Esse é um arquivo simples de configuração, é possível realizar mais configurações, realizar matchers dos e-mails e enviar para determinados grupos. Caso queira entender mais como funciona, acesse a documentação oficial.

Após criarmos esse arquivo de configuração, reinicie o serviço do Prometheus e Alertmanager:

$ docker-compose restart alertmanager

$ docker-compose restart prometheus

Validando toda a configuração

Vamos validar todo esse processo de configuração que fizemos, primeiro vamos ver o que acontece quando um dos hosts que está sendo monitorado fica down, por algum motivo seu servidor Linux não está mais acessível exportando as métricas, métricas essas que o Prometheus utiliza para saber da saúde do seu servidor.

Para simular um servidor que esteja down, vamos parar o container do node_exporter. Execute o comando:

$ docker-compose stop node_exporter

$ docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
alertmanager        "/bin/alertmanager -…"   alertmanager        running             0.0.0.0:9093->9093/tcp, :::9093->9093/tcp
grafana             "/run.sh"                grafana             running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
node_exporter       "/bin/node_exporter …"   node_exporter       exited (143)        
prometheus          "/bin/prometheus --c…"   prometheus          running             0.0.0.0:9090->9090/tcp, :::9090->9090/tcp

Podemos ver que agora o container node_exporter está com o status de exited. Abra o Prometheus no navegador e acessa o menu Alerts.

Veja que agora o status está como Pending e depois de alguns segundos ficará como Firing.

Prometheus rules status pending
Prometheus rules status pending
Prometheus rules status firing
Prometheus rules status firing

Se abrirmos agora o Alertmanager no navegador, veremos que foi enviado um alerta para ele.

Alertmanager alerta recebido
Alertmanager alerta recebido

Dentro de alguns instantes será enviado um e-mail informando que host está down, conforme imagem:

Prometheus Alert Host Down
Prometheus Alert Host Down

Show de bola. Agora vamos consertar esse host que está fora, execute o comando abaixo para subir o container do node_exporter e vamos aguardar até que o Prometheus consiga se comunicar novamente com ele.

$ docker-compose up -d

$ docker-compose ps
NAME                COMMAND                  SERVICE             STATUS              PORTS
alertmanager        "/bin/alertmanager -…"   alertmanager        running             0.0.0.0:9093->9093/tcp, :::9093->9093/tcp
grafana             "/run.sh"                grafana             running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
node_exporter       "/bin/node_exporter …"   node_exporter       running             9100/tcp
prometheus          "/bin/prometheus --c…"   prometheus          running             0.0.0.0:9090->9090/tcp, :::9090->9090/tcp

Veja no Prometheus no menu Alerts que o evento de alerta que antes estava como Firing voltará ao seu estado normal e desejado que é Inactive. Quando tudo tiver "verdinho" o Prometheus irá enviar um novo evento ao Alertmanager, só que agora um evento que informa que o host voltou a responder.

O Alertmanager por sua vez, irá remover o alerta e enviará um outro e-mail informando que o problema de host down foi resolvido.

Prometheus Alert Host UP
Prometheus Alert Host UP

Mais uma vez, show de bola. Caso você queira fazer um teste também pelo alto consumo de CPU para receber o alerta, fique a vontade, pode até dimunuir o percentual de 80% para 30% apenas para validar o envio.

Acredito que chegamos ao fim desse artigo com o recebimento desse alerta.

Download código

Todo o código dessa stack você pode baixar pelo link do Github.

Conclusão

Nesse artigo fizemos a instalação, configuração e integração do Alertmanager com o Prometheus. Criamos duas regras de alertas e validamos o envio de uma delas.

O Alertmanager em si, o uso dele é bem simples, não estarei abordando ele aqui, mas acessando a página dele é possível criar alertas por lá e silenciar um alerta por um período de tempo. Para saber mais sobre o template de notificação acesse a documentação.

Espero que tenha ajudado até aqui.

Se você encontrar algum erro, sugestões de melhorias ou se tiver alguma dúvida, deixe seu comentário abaixo.

Até a próxima.