Disparando alertas com ElastAlert2

Uma solução gratuita de alerta para quem usa a stack da Elastic

Elastic Observability com ElastAlert2.

Quando se utiliza a stack da Elastic Observability como solução de monitoramento (Elasticsearch, Kibana, Logstash, Heartbeat, Metricbeat, Filebeat, APM, e etc) surge a necessidade de disparar alertas na ocorrência de determinados eventos.

Para quem faz uso de um ecossistema Elastic sob licença Platinum ou Enterprise, o Connectors do Kibana pode ser usado para enviar alertas para diferentes destinos: Email, Slack, PagerDuty, Opsgenie, e etc.

Mas para quem não está usando uma versão paga da Elastic terá que usar alguma solução da comunidade, a mais conhecida é o ElastAlert2.

O ElastAlert é desenvolvido em Python, e foi inicialmente mantido pelo pessoal da Yelp (um serviço para a avaliação de estabelecimentos comerciais). Mas com o passar do tempo eles deixaram de interagir com a comunidade, fazendo com que um dos contribuidores criasse um fork do projeto dando continuidade sob o nome de ElastAlert2.

Basicamente ele funciona assim:

  1. Na inicialização, ele verifica a existência dos índices elastalert, elastalert_status, elastalert_error e silence. Caso eles não existam, serão criados automaticamente (pelo menos se estiver usando a versão containerizada). Estes índices são usados para persistir dados referentes aos alertas disparados e o agendamento das rules. Mais detalhes aqui.

  2. Ele lê as condições de alerta definidos em arquivos YAML. As condições de alerta funcionam baseada em consultas ao Elasticsearch. Essas condições de alerta definidas pelo usuário são chamadas de rules e podem ser do tipo frequency, flatline, any, spike, blacklist, whitelist, ou change. Cada um desses tipos de rule determinam a lógica de como os matches de um filtro será avaliado.

  3. Ele periodicamente verifica se houve match em uma dessas condições de alerta. Caso haja match, ele tomará alguma ação configurada na própria rule pelo usuário (normalmente irá disparar uma mensagem de alerta para algum sistema de on-call). A periodicidade em que a regra de alerta será avaliada é também definida pelo usuário.

A melhor forma de entender o ElasticAlert2 é vendo exemplos práticos de alertas. Vejamos um exemplo simples de rule para alerta de hosts monitorados pelo Heartbeat:

name: Synthetics
type: frequency
index: heartbeat*
filter:
- term:
    monitor.status: "down"
timeframe:
  minutes: 5
num_events: 3

Observe que essa rule tem:

  • um nome (Synthetics).

  • um tipo (frequency).

  • especifica em qual índice do Elasticsearch ele irá fazer as consultas (heartbeat*).

  • a consulta que ele irá fazer no Elasticsearch (monitor.status: "down").

  • a quantidade de ocorrências que ele espera encontrar em um dado período de tempo (pelo menos 3 ocorrências nos últimos 5 minutos).

Mas se essa rule der match ela vai fazer... nada!

Precisamos configurar um alerta nessa rule (que pode ser um comando, email, Slack, Opsgenie, PagerDuty, Alertmanager, e etc). A lista completa você vê aqui. Supondo que usamos o Opsgenie, a configuração completa seria:

name: Synthetics
type: frequency
index: heartbeat*
filter:
- term:
    monitor.status: "down"
timeframe:
  minutes: 5
num_events: 3
alert:
- "opsgenie"
opsgenie:
opsgenie_subject: "[Elastic Observability] Monitor failed for location {0} on '{1}'"
opsgenie_subject_args:
- monitor.name
- url.full
opsgenie_addr: https://api.opsgenie.com/v2/alerts
opsgenie_key: ${OPSGENIE_API_KEY}

No próprio repositório temos rules de exemplo bem didáticas. Exemplos:

  • Dispara um email para elastalert@example.com se nas últimas 4 horas tivermos pelo menos 50 ocorrências de mensagens contendo o valor some_value no campo some_field no índice logstash-* do Elasticsearch. example_frequency.yaml

  • Dispara um alerta no Opsgenie se nas últimas 2 horas houver pelo menos 50 ocorrências de mensagens contendo "hihihi" no índice logstash-* do Elasticsearch. example_opsgenie_frequency.yaml

  • Dispara um alerta no Slack, se no índice auditbeat-* houver pelo menos 20 eventos de falha de autenticação na última hora para um IP de origem específico (aqui a consulta é agregada e diferenciada pelo campo source.ip usando a diretiva query_key, com isso, dois ou mais alertas diferentes serão disparados caso dois os mais hosts registrarem falha de autenticação). ssh.yaml

O ElastAlert2 utiliza os diferentes mecanismos de consulta do Elasticsearch para a escrita dos filtros. Os filtros podem ser o term, query_string, terms, wildcard, e range. Até aqui, vimos exemplos do uso de filtros term e query_string.

Conforme já dito agora a pouco, cada um dos tipos de rule (frequency, flatline, e etc) determinam a lógica de como os matches de um filtro serão avaliados. Uma forma didática de pensar:

  • frequency: dispara um alerta se a quantidade de resultados do filtro é >= a num_events dentro do período de tempo definido em timeframe.

  • flatline: dispara um alerta se a quantidade de resultados do filtro está abaixo do definido em threshold.

  • any: se uma mensagem der match com o filtro, dispara o alerta.

  • spike: dispara um alerta se a taxa de mensagens for maior ou menor do que o esperado.

  • blacklist: dispara um alerta se uma mensagem possuir um campo presente na blacklist.

  • whitelist: dispara um alerta se uma mensagem possuir um campo que não esteja na whitelist.

  • change: alerta se em um período de tempo o valor de um campo variar.

Last updated