O problema do fechamento automático de alertas resolvidos

Uma funcionalidade básica de bons sistemas de alerta é a capacidade de fechar um alerta automaticamente quando o problema foi resolvido (até mesmo quando o problema se resolve sozinho). Infelizmente para alertas do OpsGenie, o ElastAlert não tem essa capacidade!

Mas baseando na excelente dica encontrada aqui #337 e aqui #115, é possível criar uma regra para monitorar outra regra e com isto automatizar o fechamento automático de alertas no OpsGenie, como em:

name: Service is back online
type: flatline
index: elastalert_status*
query_key: "rule_name"
filter:
- query:
    query_string:
      query: "rule_name:\"RULE_NAME_HERE\" AND matches:>0"
forget_keys: true
timeframe:
  minutes: 10
threshold: 1
alert:
- "opsgenie"
opsgenie:
opsgenie_addr: <ALIAS NAME HERE>/close?identifierType=alias
opsgenie_key: ${OPSGENIE_API_KEY}

Onde em:

  • RULE_NAME_HERE: o nome da rule em que se deseja fechar os alertas já resolvidos.

  • <ALIAS NAME HERE>: o alias do alerta no OpsGenie.

Mas esta solução funciona muito bem apenas para o fechamento de alertas que monitoram um único serviço.

Em cenários onde temos uma única rule para monitorar um conjunto variado de objetos (agregados e diferenciados por nome, e com alias do Opsgenie diferentes, como o abordado aqui), a solução acima não funciona (pois se múltiplos alertas forem disparados ele não saberá qual terá que fechar).

Para que seja possível, teríamos que ter a capacidade de fazer consultas aos campos do objeto match_body no índice elastalert. Mas por padrão esse campo não é "consultável", pois possui a indexação de seus campos desativada.

Outro empecilho é a atual integração com o OpsGenie não permitir a interpolação do endereço da API com variáveis.

Então o plano é: ativar a indexação de campos do objeto match_body e criar um script que executa um curl para o fechamento do alerta já resolvido. E aí sim conseguir criar uma regra de fechamento de alertas para o nosso cenário que executa como comando o script de fechamento de alertas.

A resolução desse problema pode ser vista no diff deste commit, onde foram feitos os seguintes passos:

1) Habilite o mapping de campos do objeto match_body: image

2) Crie um script que receba o "alias" e a "apiKey" do Opsgenie e execute um curl para fechar o alerta: image

3) Altere o Dockerfile para que ele inclua o script: image Use um alerta do tipo "command" para chamar o script. Exemplo:

      name: Deployment is back online
      type: flatline
      index: elastalert
      query_key: "match_body.kubernetes.deployment.name"
      use_terms_query: true
      doc_type: _doc
      filter:
      - query:
          query_string:
            query: "rule_name:\"k8s Deployment Monitoring\" AND match_body.num_matches:>0"
      forget_keys: true
      timeframe:
        minutes: 11
      threshold: 1
      alert:
      - "command"
      command: ["/usr/local/bin/send_alert", "%(key)s", "${OPSGENIE_API_KEY}"]

Um exemplo completo seria algo como:

k8s_deployment: |-
---
name: k8s Deployment Monitoring
type: frequency
index: metricbeat*
num_events: 59
timeframe:
  minutes: 10
metric_aggregation:
query_key: kubernetes.deployment.name
filter:
- query:
    query_string:
       query: "kubernetes.deployment.replicas.available: 0 AND kubernetes.deployment.replicas.desired:>0 AND (agent.name: cluster01 OR agent.name: cluster02 OR agent.name: cluster03)"
alert:
- "opsgenie"
realert:
  minutes: 60
opsgenie:
opsgenie_subject: "[Elastic Observability] {0}: Deployment Pods Available = 0.0 for at least 10 minutes on '{1}'"
opsgenie_subject_args:
- agent.name
- kubernetes.deployment.name
opsgenie_priority: "P1"
opsgenie_alias: "{kubernetes[deployment][name]}"
opsgenie_addr: https://api.opsgenie.com/v2/alerts
opsgenie_key: ${OPSGENIE_API_KEY}

k8s_deployment_ok: |-
---
name: Deployment is back online
type: flatline
index: elastalert
query_key: "match_body.kubernetes.deployment.name"
use_terms_query: true
doc_type: _doc
filter:
- query:
  query_string:
    query: "rule_name:\"k8s Deployment Monitoring\" AND match_body.num_matches:>0"
forget_keys: true
timeframe:
  minutes: 11
threshold: 1
alert:
- "command"
command: ["/usr/local/bin/send_alert", "%(key)s", "${OPSGENIE_API_KEY}"]

Last updated