Adding a New Alerter

Alerters are subclasses of Alerter, found in elastalert/alerts.py. They are given matches and perform some action based on that. Your alerter needs to implement two member functions, and will look something like this:

class AwesomeNewAlerter(Alerter):
    required_options = set(['some_config_option'])
    def alert(self, matches):
        ...
    def get_info(self):
        ...

You can import alert types by specifying the type as module.file.AlertName, where module is the name of a python module, and file is the name of the python file containing a Alerter subclass named AlertName.

Basics

The alerter class will be instantiated when ElastAlert starts, and be periodically passed matches through the alert method. ElastAlert also writes back info about the alert into Elasticsearch that it obtains through get_info. Several important member properties:

self.required_options: This is a set containing names of configuration options that must be present. ElastAlert will not instantiate the alert if any are missing.

self.rule: The dictionary containing the rule configuration. All options specific to the alert should be in the rule configuration file and can be accessed here.

self.pipeline: This is a dictionary object that serves to transfer information between alerts. When an alert is triggered, a new empty pipeline object will be created and each alerter can add or receive information from it. Note that alerters are called in the order they are defined in the rule file. For example, the JIRA alerter will add its ticket number to the pipeline and the email alerter will add that link if it’s present in the pipeline.

alert(self, match):

ElastAlert will call this function to send an alert. matches is a list of dictionary objects with information about the match. You can get a nice string representation of the match by calling self.rule['type'].get_match_str(match, self.rule). If this method raises an exception, it will be caught by ElastAlert and the alert will be marked as unsent and saved for later.

get_info(self):

This function is called to get information about the alert to save back to Elasticsearch. It should return a dictionary, which is uploaded directly to Elasticsearch, and should contain useful information about the alert such as the type, recipients, parameters, etc.

Tutorial

Let’s create a new alert that will write alerts to a local output file. First, create a modules folder in the base ElastAlert folder:

$ mkdir elastalert_modules
$ cd elastalert_modules
$ touch __init__.py

Now, in a file named my_alerts.py, add

from elastalert.alerts import Alerter, BasicMatchString

class AwesomeNewAlerter(Alerter):

    # By setting required_options to a set of strings
    # You can ensure that the rule config file specifies all
    # of the options. Otherwise, ElastAlert will throw an exception
    # when trying to load the rule.
    required_options = set(['output_file_path'])

    # Alert is called
    def alert(self, matches):

        # Matches is a list of match dictionaries.
        # It contains more than one match when the alert has
        # the aggregation option set
        for match in matches:

            # Config options can be accessed with self.rule
            with open(self.rule['output_file_path'], "a") as output_file:

                # basic_match_string will transform the match into the default
                # human readable string format
                match_string = str(BasicMatchString(self.rule, match))

                output_file.write(match_string)

    # get_info is called after an alert is sent to get data that is written back
    # to Elasticsearch in the field "alert_info"
    # It should return a dict of information relevant to what the alert does
    def get_info(self):
        return {'type': 'Awesome Alerter',
                'output_file': self.rule['output_file_path']}

In the rule configuration file, we are going to specify the alert by writing

alert: "elastalert_modules.my_alerts.AwesomeNewAlerter"
output_file_path: "/tmp/alerts.log"

ElastAlert will attempt to import the alert with from elastalert_modules.my_alerts import AwesomeNewAlerter. This means that the folder must be in a location where it can be imported as a python module.