Esempio n. 1
0
    def compare(self, event):
        key = hashable(lookup_es_key(event, self.rules['query_key']))
        values = []
        elastalert_logger.debug(" Previous Values of compare keys  " + str(self.occurrences))
        for val in self.rules['compound_compare_key']:
            lookup_value = lookup_es_key(event, val)
            values.append(lookup_value)
        elastalert_logger.debug(" Current Values of compare keys   " + str(values))

        changed = False
        for val in values:
            if not isinstance(val, bool) and not val and self.rules['ignore_null']:
                return False
        # If we have seen this key before, compare it to the new value
        if key in self.occurrences:
            for idx, previous_values in enumerate(self.occurrences[key]):
                elastalert_logger.debug(" " + str(previous_values) + " " + str(values[idx]))
                changed = previous_values != values[idx]
                if changed:
                    break
            if changed:
                self.change_map[key] = (self.occurrences[key], values)
                # If using timeframe, only return true if the time delta is < timeframe
                if key in self.occurrence_time:
                    changed = event[self.rules['timestamp_field']] - self.occurrence_time[key] <= self.rules['timeframe']

        # Update the current value and time
        elastalert_logger.debug(" Setting current value of compare keys values " + str(values))
        self.occurrences[key] = values
        if 'timeframe' in self.rules:
            self.occurrence_time[key] = event[self.rules['timestamp_field']]
        elastalert_logger.debug("Final result of comparision between previous and current values " + str(changed))
        return changed
Esempio n. 2
0
 def add_data(self, data):
     for document in data:
         for field in self.fields:
             value = ()
             lookup_field = field
             if type(field) == list:
                 # For composite keys, make the lookup based on all fields
                 # Make it a tuple since it can be hashed and used in dictionary lookups
                 lookup_field = tuple(field)
                 for sub_field in field:
                     lookup_result = lookup_es_key(document, sub_field)
                     if not lookup_result:
                         value = None
                         break
                     value += (lookup_result,)
             else:
                 value = lookup_es_key(document, field)
             if not value and self.rules.get('alert_on_missing_field'):
                 document['missing_field'] = lookup_field
                 self.add_match(copy.deepcopy(document))
             elif value:
                 if value not in self.seen_values[lookup_field]:
                     document['new_field'] = lookup_field
                     self.add_match(copy.deepcopy(document))
                     self.seen_values[lookup_field].append(value)
Esempio n. 3
0
    def compare(self, event):
        key = hashable(lookup_es_key(event, self.rules["query_key"]))
        val = lookup_es_key(event, self.rules["compare_key"])
        if not val and self.rules["ignore_null"]:
            return False
        changed = False

        # If we have seen this key before, compare it to the new value
        if key in self.occurrences:
            changed = self.occurrences[key] != val
            if changed:
                self.change_map[key] = (self.occurrences[key], val)

                # If using timeframe, only return true if the time delta is < timeframe
                if key in self.occurrence_time:
                    changed = (
                        event[self.rules["timestamp_field"]] - self.occurrence_time[key] <= self.rules["timeframe"]
                    )

        # Update the current value and time
        self.occurrences[key] = val
        if "timeframe" in self.rules:
            self.occurrence_time[key] = event[self.rules["timestamp_field"]]

        return changed
Esempio n. 4
0
    def _add_custom_alert_text(self):
        missing = '<MISSING VALUE>'
        alert_text = unicode(self.rule.get('alert_text', ''))
        if 'alert_text_args' in self.rule:
            alert_text_args = self.rule.get('alert_text_args')
            alert_text_values = [lookup_es_key(self.match, arg) for arg in alert_text_args]

            # Support referencing other top-level rule properties
            # This technically may not work if there is a top-level rule property with the same name
            # as an es result key, since it would have been matched in the lookup_es_key call above
            for i in xrange(len(alert_text_values)):
                if alert_text_values[i] is None:
                    alert_value = self.rule.get(alert_text_args[i])
                    if alert_value:
                        alert_text_values[i] = alert_value

            alert_text_values = [missing if val is None else val for val in alert_text_values]
            alert_text = alert_text.format(*alert_text_values)
        elif 'alert_text_kw' in self.rule:
            kw = {}
            for name, kw_name in self.rule.get('alert_text_kw').items():
                val = lookup_es_key(self.match, name)

                # Support referencing other top-level rule properties
                # This technically may not work if there is a top-level rule property with the same name
                # as an es result key, since it would have been matched in the lookup_es_key call above
                if val is None:
                    val = self.rule.get(name)

                kw[kw_name] = missing if val is None else val
            alert_text = alert_text.format(**kw)

        self.text += alert_text
Esempio n. 5
0
 def alert(self, matches):
     qk = self.rule.get('query_key', None)
     for match in matches:
         if qk in match:
             elastalert_logger.info(
                 'Alert for %s, %s at %s:' % (self.rule['name'], match[qk], lookup_es_key(match, self.rule['timestamp_field'])))
         else:
             elastalert_logger.info('Alert for %s at %s:' % (self.rule['name'], lookup_es_key(match, self.rule['timestamp_field'])))
         elastalert_logger.info(unicode(BasicMatchString(self.rule, match)))
Esempio n. 6
0
 def add_data(self, data):
     qk = self.rules.get('query_key')
     for event in data:
         if qk:
             key = hashable(lookup_es_key(event, qk))
         else:
             # If no query_key, we use the key 'all' for all events
             key = 'all'
         self.cardinality_cache.setdefault(key, {})
         self.first_event.setdefault(key, event[self.ts_field])
         value = hashable(lookup_es_key(event, self.cardinality_field))
         if value is not None:
             # Store this timestamp as most recent occurence of the term
             self.cardinality_cache[key][value] = event[self.ts_field]
             self.check_for_match(key, event)
Esempio n. 7
0
    def get_aggregation_summary_text(self, matches):
        text = ''
        if 'aggregation' in self.rule and 'summary_table_fields' in self.rule:
            summary_table_fields = self.rule['summary_table_fields']
            if not isinstance(summary_table_fields, list):
                summary_table_fields = [summary_table_fields]
            # Include a count aggregation so that we can see at a glance how many of each aggregation_key were encountered
            summary_table_fields_with_count = summary_table_fields + ['count']
            text += "Aggregation resulted in the following data for summary_table_fields ==> {0}:\n\n".format(summary_table_fields_with_count)
            text_table = Texttable()
            text_table.header(summary_table_fields_with_count)
            match_aggregation = {}

            # Maintain an aggregate count for each unique key encountered in the aggregation period
            for match in matches:
                key_tuple = tuple([unicode(lookup_es_key(match, key)) for key in summary_table_fields])
                if key_tuple not in match_aggregation:
                    match_aggregation[key_tuple] = 1
                else:
                    match_aggregation[key_tuple] = match_aggregation[key_tuple] + 1
            for keys, count in match_aggregation.iteritems():
                text_table.add_row([key for key in keys] + [count])
            text += text_table.draw() + '\n\n'

        return unicode(text)
Esempio n. 8
0
 def compare(self, event):
     term = lookup_es_key(event, self.rules["compare_key"])
     if term is None:
         return not self.rules["ignore_null"]
     if term not in self.rules["whitelist"]:
         return True
     return False
Esempio n. 9
0
 def compare(self, event):
     term = lookup_es_key(event, self.rules['compare_key'])
     if term is None:
         return not self.rules['ignore_null']
     if term not in self.rules['whitelist']:
         return True
     return False
Esempio n. 10
0
 def garbage_collect(self, timestamp):
     """ Remove all occurrence data that is beyond the timeframe away """
     stale_keys = []
     for key, window in self.occurrences.iteritems():
         if timestamp - lookup_es_key(window.data[-1][0], self.ts_field) > self.rules['timeframe']:
             stale_keys.append(key)
     map(self.occurrences.pop, stale_keys)
Esempio n. 11
0
    def _add_custom_alert_text(self):
        missing = '<MISSING VALUE>'
        alert_text = unicode(self.rule.get('alert_text', ''))
        if 'alert_text_args' in self.rule:
            alert_text_args = self.rule.get('alert_text_args')
            alert_text_values = [lookup_es_key(self.match, arg) for arg in alert_text_args]
            alert_text_values = [missing if val is None else val for val in alert_text_values]
            alert_text = alert_text.format(*alert_text_values)
        elif 'alert_text_kw' in self.rule:
            kw = {}
            for name, kw_name in self.rule.get('alert_text_kw').items():
                val = lookup_es_key(self.match, name)
                kw[kw_name] = missing if val is None else val
            alert_text = alert_text.format(**kw)

        self.text += alert_text
Esempio n. 12
0
 def add_data(self, data):
     for event in data:
         qk = self.rules.get("query_key", "all")
         if qk != "all":
             qk = hashable(lookup_es_key(event, qk))
             if qk is None:
                 qk = "other"
         self.handle_event(event, 1, qk)
Esempio n. 13
0
 def add_data(self, data):
     for event in data:
         qk = self.rules.get('query_key', 'all')
         if qk != 'all':
             qk = hashable(lookup_es_key(event, qk))
             if qk is None:
                 qk = 'other'
         self.handle_event(event, 1, qk)
Esempio n. 14
0
 def _add_custom_alert_text(self):
     alert_text = unicode(self.rule.get('alert_text', ''))
     if 'alert_text_args' in self.rule:
         alert_text_args = self.rule.get('alert_text_args')
         alert_text_values = [lookup_es_key(self.match, arg) for arg in alert_text_args]
         alert_text_values = ['<MISSING VALUE>' if val is None else val for val in alert_text_values]
         alert_text = alert_text.format(*alert_text_values)
     self.text += alert_text
Esempio n. 15
0
 def _add_custom_alert_text(self):
     alert_text = unicode(self.rule.get("alert_text", ""))
     if "alert_text_args" in self.rule:
         alert_text_args = self.rule.get("alert_text_args")
         alert_text_values = [lookup_es_key(self.match, arg) for arg in alert_text_args]
         alert_text_values = ["<MISSING VALUE>" if val is None else val for val in alert_text_values]
         alert_text = alert_text.format(*alert_text_values)
     self.text += alert_text
Esempio n. 16
0
 def get_match_str(self, match):
     lt = self.rules.get('use_local_time')
     match_ts = lookup_es_key(match, self.ts_field)
     starttime = pretty_ts(dt_to_ts(ts_to_dt(match_ts) - self.rules['timeframe']), lt)
     message = 'At least %d(%d) events occurred between %s and %s\n\n' % (self.rules['num_events'],
                                                                      match['count'],
                                                                      starttime,
                                                                      endtime)
     return message
Esempio n. 17
0
 def garbage_collect(self, timestamp):
     """ Remove all occurrence data that is beyond the timeframe away """
     stale_keys = []
     for key, window in self.occurrences.iteritems():
         if timestamp - lookup_es_key(
                 window.data[-1][0],
                 self.ts_field) > self.rules['timeframe']:
             stale_keys.append(key)
     map(self.occurrences.pop, stale_keys)
Esempio n. 18
0
 def get_match_str(self, match):
     lt = self.rules.get('use_local_time')
     match_ts = lookup_es_key(match, self.ts_field)
     starttime = pretty_ts(
         dt_to_ts(ts_to_dt(match_ts) - self.rules['timeframe']), lt)
     endtime = pretty_ts(match_ts, lt)
     message = 'At least %d events occurred between %s and %s\n\n' % (
         self.rules['num_events'], starttime, endtime)
     return message
Esempio n. 19
0
 def add_match(self, match):
     # TODO this is not technically correct
     # if the term changes multiple times before an alert is sent
     # this data will be overwritten with the most recent change
     change = self.change_map.get(hashable(lookup_es_key(match, self.rules["query_key"])))
     extra = {}
     if change:
         extra = {"old_value": change[0], "new_value": change[1]}
     super(ChangeRule, self).add_match(dict(match.items() + extra.items()))
Esempio n. 20
0
    def create_custom_title(self, matches):
        alert_subject = self.rule['alert_subject']

        if 'alert_subject_args' in self.rule:
            alert_subject_args = self.rule['alert_subject_args']
            alert_subject_values = [lookup_es_key(matches[0], arg) for arg in alert_subject_args]
            alert_subject_values = ['<MISSING VALUE>' if val is None else val for val in alert_subject_values]
            return alert_subject.format(*alert_subject_values)

        return alert_subject
Esempio n. 21
0
 def add_match(self, match):
     # TODO this is not technically correct
     # if the term changes multiple times before an alert is sent
     # this data will be overwritten with the most recent change
     change = self.change_map.get(hashable(lookup_es_key(match, self.rules['query_key'])))
     extra = {}
     if change:
         extra = {'old_value': change[0],
                  'new_value': change[1]}
     super(ChangeRule, self).add_match(dict(match.items() + extra.items()))
Esempio n. 22
0
    def create_custom_title(self, matches):
        alert_subject = self.rule['alert_subject']

        if 'alert_subject_args' in self.rule:
            alert_subject_args = self.rule['alert_subject_args']
            alert_subject_values = [lookup_es_key(matches[0], arg) for arg in alert_subject_args]
            alert_subject_values = ['<MISSING VALUE>' if val is None else val for val in alert_subject_values]
            return alert_subject.format(*alert_subject_values)

        return alert_subject
Esempio n. 23
0
    def compare(self, event):
        key = hashable(lookup_es_key(event, self.rules['query_key']))
        values = []
        elastalert_logger.debug(" Previous Values of compare keys  " +
                                str(self.occurrences))
        for val in self.rules['compound_compare_key']:
            lookup_value = lookup_es_key(event, val)
            values.append(lookup_value)
        elastalert_logger.debug(" Current Values of compare keys   " +
                                str(values))

        changed = False
        for val in values:
            if not isinstance(val,
                              bool) and not val and self.rules['ignore_null']:
                return False
        # If we have seen this key before, compare it to the new value
        if key in self.occurrences:
            for idx, previous_values in enumerate(self.occurrences[key]):
                elastalert_logger.debug(" " + str(previous_values) + " " +
                                        str(values[idx]))
                changed = previous_values != values[idx]
                if changed:
                    break
            if changed:
                self.change_map[key] = (self.occurrences[key], values)
                # If using timeframe, only return true if the time delta is < timeframe
                if key in self.occurrence_time:
                    changed = event[
                        self.rules['timestamp_field']] - self.occurrence_time[
                            key] <= self.rules['timeframe']

        # Update the current value and time
        elastalert_logger.debug(
            " Setting current value of compare keys values " + str(values))
        self.occurrences[key] = values
        if 'timeframe' in self.rules:
            self.occurrence_time[key] = event[self.rules['timestamp_field']]
        elastalert_logger.debug(
            "Final result of comparision between previous and current values "
            + str(changed))
        return changed
Esempio n. 24
0
    def _add_custom_alert_text(self):
        missing = '<MISSING VALUE>'
        alert_text = unicode(self.rule.get('alert_text', ''))
        if 'alert_text_args' in self.rule:
            alert_text_args = self.rule.get('alert_text_args')
            alert_text_values = [
                lookup_es_key(self.match, arg) for arg in alert_text_args
            ]
            alert_text_values = [
                missing if val is None else val for val in alert_text_values
            ]
            alert_text = alert_text.format(*alert_text_values)
        elif 'alert_text_kw' in self.rule:
            kw = {}
            for name, kw_name in self.rule.get('alert_text_kw').items():
                val = lookup_es_key(self.match, name)
                kw[kw_name] = missing if val is None else val
            alert_text = alert_text.format(**kw)

        self.text += alert_text
Esempio n. 25
0
 def add_match(self, match):
     # TODO this is not technically correct
     # if the term changes multiple times before an alert is sent
     # this data will be overwritten with the most recent change
     change = self.change_map.get(hashable(lookup_es_key(match, self.rules['query_key'])))
     extra = {}
     if change:
         extra = {'old_value': change[0],
                  'new_value': change[1]}
         elastalert_logger.debug("Description of the changed records  " + str(dict(match.items() + extra.items())))
     super(ChangeRule, self).add_match(dict(match.items() + extra.items()))
Esempio n. 26
0
 def add_data(self, data):
     for document in data:
         for field in self.fields:
             value = lookup_es_key(document, field)
             if not value and self.rules.get('alert_on_missing_field'):
                 document['missing_field'] = field
                 self.add_match(document)
             elif value:
                 if value not in self.seen_values[field]:
                     document['new_field'] = field
                     self.add_match(document)
                     self.seen_values[field].append(value)
Esempio n. 27
0
 def add_data(self, data):
     for document in data:
         for field in self.fields:
             value = lookup_es_key(document, field)
             if not value and self.rules.get('alert_on_missing_field'):
                 document['missing_field'] = field
                 self.add_match(document)
             elif value:
                 if value not in self.seen_values[field]:
                     document['new_field'] = field
                     self.add_match(document)
                     self.seen_values[field].append(value)
Esempio n. 28
0
 def _add_custom_alert_text(self):
     alert_text = unicode(self.rule.get('alert_text', ''))
     if 'alert_text_args' in self.rule:
         alert_text_args = self.rule.get('alert_text_args')
         alert_text_values = [
             lookup_es_key(self.match, arg) for arg in alert_text_args
         ]
         alert_text_values = [
             '<MISSING VALUE>' if val is None else val
             for val in alert_text_values
         ]
         alert_text = alert_text.format(*alert_text_values)
     self.text += alert_text
Esempio n. 29
0
    def compare(self, event):
        key = hashable(lookup_es_key(event, self.rules['query_key']))
        val = lookup_es_key(event, self.rules['compare_key'])
        if not val and self.rules['ignore_null']:
            return False
        changed = False

        # If we have seen this key before, compare it to the new value
        if key in self.occurrences:
            changed = self.occurrences[key] != val
            if changed:
                self.change_map[key] = (self.occurrences[key], val)

                # If using timeframe, only return true if the time delta is < timeframe
                if key in self.occurrence_time:
                    changed = event[self.rules['timestamp_field']] - self.occurrence_time[key] <= self.rules['timeframe']

        # Update the current value and time
        self.occurrences[key] = val
        if 'timeframe' in self.rules:
            self.occurrence_time[key] = event[self.rules['timestamp_field']]

        return changed
Esempio n. 30
0
 def add_data(self, data):
     qk = self.rules.get('query_key')
     for event in data:
         if qk:
             key = hashable(lookup_es_key(event, qk))
         else:
             # If no query_key, we use the key 'all' for all events
             key = 'all'
         self.cardinality_cache.setdefault(key, {})
         self.first_event.setdefault(key, event[self.ts_field])
         if self.cardinality_field in event:
             # Store this timestamp as most recent occurence of the term
             self.cardinality_cache[key][event[self.cardinality_field]] = event[self.ts_field]
             self.check_for_match(key, event)
Esempio n. 31
0
    def _add_custom_alert_text(self):
        missing = '<MISSING VALUE>'
        alert_text = unicode(self.rule.get('alert_text', ''))
        if 'alert_text_args' in self.rule:
            alert_text_args = self.rule.get('alert_text_args')
            alert_text_values = [
                lookup_es_key(self.match, arg) for arg in alert_text_args
            ]

            # Support referencing other top-level rule properties
            # This technically may not work if there is a top-level rule property with the same name
            # as an es result key, since it would have been matched in the lookup_es_key call above
            for i in xrange(len(alert_text_values)):
                if alert_text_values[i] is None:
                    alert_value = self.rule.get(alert_text_args[i])
                    if alert_value:
                        alert_text_values[i] = alert_value

            alert_text_values = [
                missing if val is None else val for val in alert_text_values
            ]
            alert_text = alert_text.format(*alert_text_values)
        elif 'alert_text_kw' in self.rule:
            kw = {}
            for name, kw_name in self.rule.get('alert_text_kw').items():
                val = lookup_es_key(self.match, name)

                # Support referencing other top-level rule properties
                # This technically may not work if there is a top-level rule property with the same name
                # as an es result key, since it would have been matched in the lookup_es_key call above
                if val is None:
                    val = self.rule.get(name)

                kw[kw_name] = missing if val is None else val
            alert_text = alert_text.format(**kw)

        self.text += alert_text
Esempio n. 32
0
    def add_data(self, data):
        if 'query_key' in self.rules:
            qk = self.rules['query_key']
        else:
            qk = None

        for event in data:
            if qk:
                key = hashable(lookup_es_key(event, qk))
            else:
                # If no query_key, we use the key 'all' for all events
                key = 'all'

            # Store the timestamps of recent occurrences, per key
            self.occurrences.setdefault(key, EventWindow(self.rules['timeframe'], getTimestamp=self.get_ts)).append((event, 1))
            self.check_for_match(key)
Esempio n. 33
0
    def create_custom_title(self, matches):
        opsgenie_subject = unicode(self.rule['opsgenie_subject'])

        if self.opsgenie_subject_args:
            opsgenie_subject_values = [lookup_es_key(matches[0], arg) for arg in self.opsgenie_subject_args]

            for i in xrange(len(opsgenie_subject_values)):
                if opsgenie_subject_values[i] is None:
                    alert_value = self.rule.get(self.opsgenie_subject_args[i])
                    if alert_value:
                        opsgenie_subject_values[i] = alert_value

            opsgenie_subject_values = ['<MISSING VALUE>' if val is None else val for val in opsgenie_subject_values]
            return opsgenie_subject.format(*opsgenie_subject_values)

        return opsgenie_subject
Esempio n. 34
0
    def create_custom_title(self, matches):
        opsgenie_subject = unicode(self.rule['opsgenie_subject'])

        if self.opsgenie_subject_args:
            opsgenie_subject_values = [lookup_es_key(matches[0], arg) for arg in self.opsgenie_subject_args]

            for i, subject_value in enumerate(opsgenie_subject_values):
                if subject_value is None:
                    alert_value = self.rule.get(self.opsgenie_subject_args[i])
                    if alert_value:
                        opsgenie_subject_values[i] = alert_value

            opsgenie_subject_values = ['<MISSING VALUE>' if val is None else val for val in opsgenie_subject_values]
            return opsgenie_subject.format(*opsgenie_subject_values)

        return opsgenie_subject
Esempio n. 35
0
    def add_data(self, data):
        if 'query_key' in self.rules:
            qk = self.rules['query_key']
        else:
            qk = None

        for event in data:
            if qk:
                key = hashable(lookup_es_key(event, qk))
            else:
                # If no query_key, we use the key 'all' for all events
                key = 'all'

            # Store the timestamps of recent occurrences, per key
            self.occurrences.setdefault(key, EventWindow(self.rules['timeframe'], getTimestamp=self.get_ts)).append((event, 1))
            self.check_for_match(key)
Esempio n. 36
0
    def add_data(self, data):
        if 'query_key' in self.rules:
            qk = self.rules['query_key']
        else:
            qk = None

        for event in data:
            if qk:
                key = hashable(lookup_es_key(event, qk))
            else:
                # If no query_key, we use the key 'all' for all events
                key = 'all'

            # Store the timestamps of recent occurrences, per key
            self.occurrences.setdefault(key, EventWindow(self.rules['timeframe'], getTimestamp=self.get_ts)).append((event, 1))

        # Only check for match _once_ after adding all the events discovered in this run
        # If the current running count is 1, and the threshold is 10, and we go to add 8 entries
        # it should only count as a single match, and not 8 consecutive ones.
        self.check_for_match(key)
Esempio n. 37
0
    def create_custom_title(self, matches):
        alert_subject = unicode(self.rule['alert_subject'])

        if 'alert_subject_args' in self.rule:
            alert_subject_args = self.rule['alert_subject_args']
            alert_subject_values = [lookup_es_key(matches[0], arg) for arg in alert_subject_args]

            # Support referencing other top-level rule properties
            # This technically may not work if there is a top-level rule property with the same name
            # as an es result key, since it would have been matched in the lookup_es_key call above
            for i in xrange(len(alert_subject_values)):
                if alert_subject_values[i] is None:
                    alert_value = self.rule.get(alert_subject_args[i])
                    if alert_value:
                        alert_subject_values[i] = alert_value

            alert_subject_values = ['<MISSING VALUE>' if val is None else val for val in alert_subject_values]
            return alert_subject.format(*alert_subject_values)

        return alert_subject
Esempio n. 38
0
    def add_data(self, data):
        if 'query_key' in self.rules:
            qk = self.rules['query_key']
        else:
            qk = None

        for event in data:
            if qk:
                key = hashable(lookup_es_key(event, qk))
            else:
                # If no query_key, we use the key 'all' for all events
                key = 'all'

            # Store the timestamps of recent occurrences, per key
            self.occurrences.setdefault(key, EventWindow(self.rules['timeframe'], getTimestamp=self.get_ts)).append((event, 1))
            self.check_for_match(key, end=False)

        # We call this multiple times with the 'end' parameter because subclasses
        # may or may not want to check while only partial data has been added
        if key in self.occurrences:  # could have been emptied by previous check
            self.check_for_match(key, end=True)
Esempio n. 39
0
    def add_data(self, data):
        if 'query_key' in self.rules:
            qk = self.rules['query_key']
        else:
            qk = None

        for event in data:
            if qk:
                key = hashable(lookup_es_key(event, qk))
            else:
                # If no query_key, we use the key 'all' for all events
                key = 'all'

            # Store the timestamps of recent occurrences, per key
            self.occurrences.setdefault(key, EventWindow(self.rules['timeframe'], getTimestamp=self.get_ts)).append((event, 1))
            self.check_for_match(key, end=False)

        # We call this multiple times with the 'end' parameter because subclasses
        # may or may not want to check while only partial data has been added
        if key in self.occurrences:  # could have been emptied by previous check
            self.check_for_match(key, end=True)
Esempio n. 40
0
    def _parse_responders(self, responders, responder_args, matches, default_responders):
        if responder_args:
            formated_responders = list()
            responders_values = dict((k, lookup_es_key(matches[0], v)) for k, v in responder_args.iteritems())
            responders_values = dict((k, v) for k, v in responders_values.iteritems() if v)

            for responder in responders:
                responder = unicode(responder)
                try:
                    formated_responders.append(responder.format(**responders_values))
                except KeyError as error:
                    logging.warn("OpsGenieAlerter: Cannot create responder for OpsGenie Alert. Key not foud: %s. " % (error))
            if not formated_responders:
                logging.warn("OpsGenieAlerter: no responders can be formed. Trying the default responder ")
                if not default_responders:
                    logging.warn("OpsGenieAlerter: default responder not set. Falling back")
                    formated_responders = responders
                else:
                    formated_responders = default_responders
            responders = formated_responders
        return responders
Esempio n. 41
0
    def add_data(self, data):
        if 'query_key' in self.rules:
            qk = self.rules['query_key']
        else:
            qk = None

        for event in data:
            if qk:
                key = hashable(lookup_es_key(event, qk))
            else:
                # If no query_key, we use the key 'all' for all events
                key = 'all'

            # Store the timestamps of recent occurrences, per key
            self.occurrences.setdefault(
                key,
                EventWindow(self.rules['timeframe'],
                            getTimestamp=self.get_ts)).append((event, 1))

        # Only check for match _once_ after adding all the events discovered in this run
        # If the current running count is 1, and the threshold is 10, and we go to add 8 entries
        # it should only count as a single match, and not 8 consecutive ones.
        self.check_for_match(key)
Esempio n. 42
0
 def compare(self, data):
     if self.rule.get('condition').get('script'):
         if self.rule.get('condition').get('script').get('inline'):
             script = self.rule.get('condition').get('script').get('inline')
             ret = ruby_alert_determine(['ruby', 'elasticwatcher/script_inline_alert_check.rb', '--query_result', json.dumps(data), '--script', script])
             
             if ret[1] == 'true':
                 return True
             else:
                 return False
         else:
             ruby_script_name = self.rule.get('condition').get('script').get('name')
             determine_result = ruby_alert_determine(['ruby', 'rules/'+ruby_script_name, '--query_result', json.dumps(data)])
             if determine_result[1] == "true":
                 return True
             else:
                 return False        
     else:
         term = lookup_es_key(data, self.rule.get('condition').get('compare_key'))
         if term is None:
             return not self.rule.get('condition').get('ignore_null')
         if OPS_DICT.get(self.rule.get('condition').get('operator'))(term, self.rule.get('condition').get('expected')):
             return True
         return False
Esempio n. 43
0
 def comment_on_ticket(self, ticket, match):
     text = unicode(JiraFormattedMatchString(self.rule, match))
     timestamp = pretty_ts(lookup_es_key(match, self.rule['timestamp_field']))
     comment = "This alert was triggered again at %s\n%s" % (timestamp, text)
     self.client.add_comment(ticket, comment)
Esempio n. 44
0
 def compare(self, event):
     term = lookup_es_key(event, self.rules["compare_key"])
     if term in self.rules["blacklist"]:
         return True
     return False
Esempio n. 45
0
    def alert(self, matches):

        if False:
            print "*********** STACK ***********"
            import traceback
            traceback.print_stack()
            print "*********** MATCHES ***********"
            print matches
            print "*********** RULES ************"
            print self.rule

        if 'template_text_content' in self.rule:
            text = self.rule['template_text_content']
        elif 'template_text_file' in self.rule:
            with open(self.rule['template_text_file'], 'r') as f:
                text = f.read()
        else:
            text = '{{ matches|length }} items found'
        if 'template_html_content' in self.rule:
            html = self.rule['template_html_content']
        elif 'template_html_file' in self.rule:
            with open(self.rule['template_html_file'], 'r') as f:
                html = f.read()
        else:
            html = '{{ matches|length }} items found'

        if 'email_from_field' in self.rule:
            recipient = lookup_es_key(matches[0],
                                      self.rule['email_from_field'])
            if isinstance(recipient, basestring):
                if '@' in recipient:
                    to_addr = [recipient]
                elif 'email_add_domain' in self.rule:
                    to_addr = [recipient + self.rule['email_add_domain']]
            elif isinstance(recipient, list):
                to_addr = recipient
                if 'email_add_domain' in self.rule:
                    to_addr = [
                        name + self.rule['email_add_domain']
                        for name in to_addr
                    ]

        es_conn_conf = util.build_es_conn_config(self.rule)

        env = {
            'rule':
            self.rule,
            'matches':
            matches,
            'pipeline':
            self.pipeline,
            'jira_server':
            self.pipeline['jira_server'] if
            (self.pipeline and 'jira_server' in self.pipeline) else None,
            'jira_ticket':
            self.pipeline['jira_ticket'] if
            (self.pipeline and 'jira_ticket' in self.pipeline) else None,
            'es':
            util.elasticsearch_client(es_conn_conf),
            'json':
            json,
            'util':
            util,
            'datetime':
            datetime,
            'kibana_context_args':
            kibana4_context_args,
        }

        text = Environment().from_string(text).render(**env)
        html = Environment().from_string(html).render(**env)

        messageRoot = MIMEMultipart('related')
        messageRoot['Subject'] = _encode_str(self.create_title(matches))
        messageRoot['From'] = _encode_str(self.from_addr)
        if 'email_from_field' in self.rule:
            messageRoot['To'] = _convert_to_strings(to_addr)
        else:
            messageRoot['To'] = _convert_to_strings(self.rule['email'])

        if self.rule.get('email_reply_to'):
            messageRoot['Reply-To'] = _convert_to_strings(
                self.rule.get('email_reply_to'))

        messageRoot.preamble = 'This is a multi-part message in MIME format.'

        # Encapsulate the plain and HTML versions of the message body in an
        # 'alternative' part, so message agents can decide which they want to display.
        msgAlternative = MIMEMultipart('alternative')
        msgAlternative.attach(MIMEText(_encode_str(text), 'plain'))
        msgAlternative.attach(MIMEText(_encode_str(html), 'html'))
        messageRoot.attach(msgAlternative)

        try:
            if self.smtp_ssl:
                if self.smtp_port:
                    self.smtp = SMTP_SSL(self.smtp_host, self.smtp_port)
                else:
                    self.smtp = SMTP_SSL(self.smtp_host)
            else:
                if self.smtp_port:
                    self.smtp = SMTP(self.smtp_host, self.smtp_port)
                else:
                    self.smtp = SMTP(self.smtp_host)
                self.smtp.ehlo()
                if self.smtp.has_extn('STARTTLS'):
                    self.smtp.starttls()
            if 'smtp_auth_file' in self.rule:
                self.smtp.login(self.user, self.password)
        except (SMTPException, error) as e:
            raise EAException("Error connecting to SMTP host: %s" % (e))
        except SMTPAuthenticationError as e:
            raise EAException("SMTP username/password rejected: %s" % (e))

        self.smtp.sendmail(messageRoot['From'], self.rule['email'],
                           messageRoot.as_string())
        self.smtp.close()

        elastalert_logger.info("Sent email to %s for rule: %s" %
                               (self.rule['email'], self.rule['name']))
Esempio n. 46
0
def lookup_value_source(d, key):
    hit = d.get('hits').get('hits')[0]['_source']
    return lookup_es_key(hit, key)
Esempio n. 47
0
 def compare(self, event):
     term = lookup_es_key(event, self.rules['compare_key'])
     if term in self.rules['blacklist']:
         return True
     return False
Esempio n. 48
0
 def compare(self, event):
     term = lookup_es_key(event, self.rules['compare_key'])
     if term in self.rules['blacklist']:
         return True
     return False