Skip to content

Commit

Permalink
Merge pull request Yelp#81 from 3vanlock/add-datadog-alerter
Browse files Browse the repository at this point in the history
Add alert handler to create Datadog Events
  • Loading branch information
jertel committed Apr 23, 2021
2 parents 7b99e21 + a6e8673 commit 1c6ed32
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 1 deletion.
12 changes: 12 additions & 0 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,18 @@ Example usage using new-style format::
command: ["/bin/send_alert", "--username", "{match[username]}"]


Datadog
~~~~~~~

This alert will create a [Datadog Event](https://docs.datadoghq.com/events/). Events are limited to 4000 characters. If an event is sent that contains
a message that is longer than 4000 characters, only his first 4000 characters will be displayed.

This alert requires two additional options:

``datadog_api_key``: [Datadog API key](https://docs.datadoghq.com/account_management/api-app-keys/#api-keys)

``datadog_app_key``: [Datadog application key](https://docs.datadoghq.com/account_management/api-app-keys/#application-keys)

Email
~~~~~

Expand Down
31 changes: 31 additions & 0 deletions elastalert/alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2231,3 +2231,34 @@ def get_info(self):
"type": "chatwork",
"chatwork_room_id": self.chatwork_room_id
}


class DatadogAlerter(Alerter):
''' Creates a Datadog Event for each alert '''
required_options = frozenset(['datadog_api_key', 'datadog_app_key'])

def __init__(self, rule):
super(DatadogAlerter, self).__init__(rule)
self.dd_api_key = self.rule.get('datadog_api_key', None)
self.dd_app_key = self.rule.get('datadog_app_key', None)

def alert(self, matches):
url = 'https://api.datadoghq.com/api/v1/events'
headers = {
'Content-Type': 'application/json',
'DD-API-KEY': self.dd_api_key,
'DD-APPLICATION-KEY': self.dd_app_key
}
payload = {
'title': self.create_title(matches),
'text': self.create_alert_body(matches)
}
try:
response = requests.post(url, data=json.dumps(payload, cls=DateTimeEncoder), headers=headers)
response.raise_for_status()
except RequestException as e:
raise EAException('Error posting event to Datadog: %s' % e)
elastalert_logger.info('Alert sent to Datadog')

def get_info(self):
return {'type': 'datadog'}
3 changes: 2 additions & 1 deletion elastalert/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ class RulesLoader(object):
'zabbix': ZabbixAlerter,
'discord': alerts.DiscordAlerter,
'dingtalk': alerts.DingTalkAlerter,
'chatwork': alerts.ChatworkAlerter
'chatwork': alerts.ChatworkAlerter,
'datadog': alerts.DatadogAlerter
}

# A partial ordering of alert types. Relative order will be preserved in the resulting alerts list
Expand Down
37 changes: 37 additions & 0 deletions tests/alerts_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from elastalert.alerts import Alerter
from elastalert.alerts import BasicMatchString
from elastalert.alerts import CommandAlerter
from elastalert.alerts import DatadogAlerter
from elastalert.alerts import EmailAlerter
from elastalert.alerts import HTTPPostAlerter
from elastalert.alerts import JiraAlerter
Expand Down Expand Up @@ -2296,3 +2297,39 @@ def test_alert_subject_size_limit_with_args(ea):
alert = Alerter(rule)
alertSubject = alert.create_custom_title([{'test_term': 'test_value', '@timestamp': '2014-10-31T00:00:00'}])
assert 6 == len(alertSubject)


def test_datadog_alerter():
rule = {
'name': 'Test Datadog Event Alerter',
'type': 'any',
'datadog_api_key': 'test-api-key',
'datadog_app_key': 'test-app-key',
'alert': [],
'alert_subject': 'Test Datadog Event Alert'
}
rules_loader = FileRulesLoader({})
rules_loader.load_modules(rule)
alert = DatadogAlerter(rule)
match = {
'@timestamp': '2021-01-01T00:00:00',
'name': 'datadog-test-name'
}
with mock.patch('requests.post') as mock_post_request:
alert.alert([match])

expected_data = {
'title': rule['alert_subject'],
'text': "Test Datadog Event Alerter\n\n@timestamp: 2021-01-01T00:00:00\nname: datadog-test-name\n"
}
mock_post_request.assert_called_once_with(
"https://api.datadoghq.com/api/v1/events",
data=mock.ANY,
headers={
'Content-Type': 'application/json',
'DD-API-KEY': rule['datadog_api_key'],
'DD-APPLICATION-KEY': rule['datadog_app_key']
}
)
actual_data = json.loads(mock_post_request.call_args_list[0][1]['data'])
assert expected_data == actual_data

0 comments on commit 1c6ed32

Please sign in to comment.