Skip to content

Commit

Permalink
Merge pull request #503 from nsano-rururu/add_alertmanager
Browse files Browse the repository at this point in the history
Added Support Alertmanager
  • Loading branch information
jertel authored Oct 9, 2021
2 parents f56cfd8 + 2af0db0 commit cf7987f
Show file tree
Hide file tree
Showing 7 changed files with 506 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
- None

## New features
- None
- [Alertmanager] Added support for Alertmanager - [#503](https://github.com/jertel/elastalert2/pull/503) - @nsano-rururu

## Other changes
- [Docs] Add exposed metrics documentation - [#498](https://github.com/jertel/elastalert2/pull/498) - @thisisxgp
Expand Down
1 change: 1 addition & 0 deletions docs/source/elastalert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Several rule types with common monitoring paradigms are included with ElastAlert
Currently, we have support built in for these alert types:

- Alerta
- Alertmanager
- AWS SES (Amazon Simple Email Service)
- AWS SNS (Amazon Simple Notification Service)
- Chatwork
Expand Down
49 changes: 49 additions & 0 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,55 @@ Example usage using new-style format::
alerta_attributes_values: ["{key}", "{logdate}", "{sender_ip}" ]
alerta_text: "Probe {hostname} is UP at {logdate} GMT"

Alertmanager
~~~~~~~~~~~~

This alert type will send alerts to Alertmanager postAlerts. ``alert_subject`` and ``alert_text`` are passed as the annotations labeled ``summary`` and ``description`` accordingly. The labels can be changed.
See https://prometheus.io/docs/alerting/clients/ for more details about the Alertmanager alert format.

Required:

``alertmanager_hosts``: The list of hosts pointing to the Alertmanager.

Optional:

``alertmanager_api_version``: Defaults to `v1`. Set to `v2` to enable the Alertmanager V2 API postAlerts.

``alertmanager_alertname``: ``alertname`` is the only required label. Defaults to using the rule name of the alert.

``alertmanager_labels``: Key:value pairs of arbitrary labels to be attached to every alert. Keys should match the regular expression ``^[a-zA-Z_][a-zA-Z0-9_]*$``.

``alertmanager_annotations``: Key:value pairs of arbitrary annotations to be attached to every alert. Keys should match the regular expression ``^[a-zA-Z_][a-zA-Z0-9_]*$``.

``alertmanager_fields``: Key:value pairs of labels and corresponding match fields. When using ``alertmanager_fields`` you can access nested fields and index into arrays the same way as with ``alert_text_args``. Keys should match the regular expression ``^[a-zA-Z_][a-zA-Z0-9_]*$``. This dictionary will be merged with the ``alertmanager_labels``.

``alertmanager_alert_subject_labelname``: Rename the annotations' label name for ``alert_subject``. Default is ``summary``.

``alertmanager_alert_text_labelname``: Rename the annotations' label name for ``alert_text``. Default is ``description``.

``alertmanager_proxy``: By default ElastAlert 2 will not use a network proxy to send notifications to Alertmanager. Set this option using ``hostname:port`` if you need to use a proxy. only supports https.

``alertmanager_ca_certs``: Set this option to ``True`` if you want to validate the SSL certificate.

``alertmanager_ignore_ssl_errors``: By default ElastAlert 2 will verify SSL certificate. Set this option to ``False`` if you want to ignore SSL errors.

``alertmanager_timeout``: You can specify a timeout value, in seconds, for making communicating with Alertmanager. The default is 10. If a timeout occurs, the alert will be retried next time ElastAlert 2 cycles.

Example usage::

alert:
- "alertmanager"
alertmanager_hosts:
- "http://alertmanager:9093"
alertmanager_alertname: "Title"
alertmanager_annotations:
severity: "error"
alertmanager_labels:
source: "elastalert"
alertmanager_fields:
msg: "message"
log: "@log_name"

AWS SES (Amazon Simple Email Service)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
83 changes: 83 additions & 0 deletions elastalert/alerters/alertmanager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import json
import warnings

import requests
from requests import RequestException

from elastalert.alerts import Alerter, DateTimeEncoder
from elastalert.util import EAException, elastalert_logger, lookup_es_key


class AlertmanagerAlerter(Alerter):
""" Sends an alert to Alertmanager """

required_options = frozenset({'alertmanager_hosts'})

def __init__(self, rule):
super(AlertmanagerAlerter, self).__init__(rule)
self.api_version = self.rule.get('alertmanager_api_version', 'v1')
self.hosts = self.rule.get('alertmanager_hosts')
self.alertname = self.rule.get('alertmanager_alertname', self.rule.get('name'))
self.labels = self.rule.get('alertmanager_labels', dict())
self.annotations = self.rule.get('alertmanager_annotations', dict())
self.fields = self.rule.get('alertmanager_fields', dict())
self.title_labelname = self.rule.get('alertmanager_alert_subject_labelname', 'summary')
self.body_labelname = self.rule.get('alertmanager_alert_text_labelname', 'description')
self.proxies =self.rule.get('alertmanager_proxy', None)
self.ca_certs = self.rule.get('alertmanager_ca_certs')
self.ignore_ssl_errors = self.rule.get('alertmanager_ignore_ssl_errors', False)
self.timeout = self.rule.get('alertmanager_timeout', 10)

@staticmethod
def _json_or_string(obj):
"""helper to encode non-string objects to JSON"""
if isinstance(obj, str):
return obj
return json.dumps(obj, cls=DateTimeEncoder)

def alert(self, matches):
headers = {'content-type': 'application/json'}
proxies = {'https': self.proxies} if self.proxies else None

self.labels.update({
label: self._json_or_string(lookup_es_key(matches[0], term))
for label, term in self.fields.items()})
self.labels.update(
alertname=self.alertname,
elastalert_rule=self.rule.get('name'))
self.annotations.update({
self.title_labelname: self.create_title(matches),
self.body_labelname: self.create_alert_body(matches)})
payload = {
'annotations': self.annotations,
'labels': self.labels
}

for host in self.hosts:
try:
url = '{}/api/{}/alerts'.format(host, self.api_version)

if self.ca_certs:
verify = self.ca_certs
else:
verify = not self.ignore_ssl_errors
if self.ignore_ssl_errors:
requests.packages.urllib3.disable_warnings()

response = requests.post(
url,
data=json.dumps([payload], cls=DateTimeEncoder),
headers=headers,
verify=verify,
proxies=proxies,
timeout=self.timeout
)

warnings.resetwarnings()
response.raise_for_status()
except RequestException as e:
raise EAException("Error posting to Alertmanager: %s" % e)
elastalert_logger.info("Alert sent to Alertmanager")

def get_info(self):
return {'type': 'alertmanager'}
2 changes: 2 additions & 0 deletions elastalert/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from elastalert import alerts
from elastalert import enhancements
from elastalert import ruletypes
from elastalert.alerters.alertmanager import AlertmanagerAlerter
from elastalert.alerters.email import EmailAlerter
from elastalert.alerters.jira import JiraAlerter
from elastalert.alerters.mattermost import MattermostAlerter
Expand Down Expand Up @@ -88,6 +89,7 @@ class RulesLoader(object):

# Used to map names of alerts to their classes
alerts_mapping = {
'alertmanager': AlertmanagerAlerter,
'tencent_sms': TencentSMSAlerter,
'email': EmailAlerter,
'jira': JiraAlerter,
Expand Down
46 changes: 46 additions & 0 deletions elastalert/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,52 @@ properties:
alerta_attributes_keys: {type: array, items: {type: string}}
alerta_attributes_values: {type: array, items: {type: string}} # Python format string

### Alertmanager
alertmanager_hosts: {type: array, items: {type: string}}
alertmanager_api_version: {type: string, enum: ['v1', 'v2']}
alertmanager_alert_subject_labelname: {type: string}
alertmanager_alert_text_labelname: {type: string}
alertmanager_proxy: {type: string}
alertmanager_ca_certs: {type: boolean}
alertmanager_ignore_ssl_errors: {type: boolean}
alertmanager_timeout: {type: integer}
alertmanager_labels:
type: object
minProperties: 1
patternProperties:
"^.+$":
oneOf:
- type: string
- type: object
additionalProperties: false
required: [field]
properties:
field: {type: string, minLength: 1}
alertmanager_annotations:
type: object
minProperties: 1
patternProperties:
"^.+$":
oneOf:
- type: string
- type: object
additionalProperties: false
required: [field]
properties:
field: {type: string, minLength: 1}
alertmanager_fields:
type: object
minProperties: 1
patternProperties:
"^.+$":
oneOf:
- type: string
- type: object
additionalProperties: false
required: [field]
properties:
field: {type: string, minLength: 1}

### AWS SES
ses_email: *arrayOfString
ses_from_addr: {type: string}
Expand Down
Loading

0 comments on commit cf7987f

Please sign in to comment.