From 9fcd5bd2ad8d35a34854cc086886296da1983615 Mon Sep 17 00:00:00 2001 From: Florian GAULTIER Date: Tue, 28 May 2019 20:58:41 +0200 Subject: [PATCH] Add related_events capability to cardinality (cherry picked from commit 87db71dde09a148f7319c62fd794de998b8bbf44) --- elastalert/ruletypes.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/elastalert/ruletypes.py b/elastalert/ruletypes.py index a8845ca92..5ffb867ed 100644 --- a/elastalert/ruletypes.py +++ b/elastalert/ruletypes.py @@ -52,12 +52,14 @@ def add_match(self, event): :param event: The matching event, a dictionary of terms. """ + + copy_event = copy.deepcopy(event) # Convert datetime's back to timestamps ts = self.rules.get('timestamp_field') - if ts in event: - event[ts] = dt_to_ts(event[ts]) + if ts in copy_event: + copy_event[ts] = dt_to_ts(copy_event[ts]) - self.matches.append(copy.deepcopy(event)) + self.matches.append(copy_event) def get_match_str(self, match): """ Returns a string that gives more context about a match. @@ -907,6 +909,7 @@ def __init__(self, *args): self.cardinality_cache = {} self.first_event = {} self.timeframe = self.rules['timeframe'] + self.attach_related = self.rules.get('attach_related', False) def add_data(self, data): qk = self.rules.get('query_key') @@ -921,7 +924,7 @@ def add_data(self, data): 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] = lookup_es_key(event, self.ts_field) + self.cardinality_cache[key][value] = event self.check_for_match(key, event) def check_for_match(self, key, event, gc=True): @@ -937,13 +940,17 @@ def check_for_match(self, key, event, gc=True): self.check_for_match(key, event, False) else: self.first_event.pop(key, None) + if self.attach_related: + event['related_events'] = [ + occurence for _, occurence in self.cardinality_cache[key].items() if occurence['_id'] != event['_id'] + ] self.add_match(event) def garbage_collect(self, timestamp): """ Remove all occurrence data that is beyond the timeframe away """ for qk, terms in self.cardinality_cache.items(): for term, last_occurence in terms.items(): - if timestamp - last_occurence > self.rules['timeframe']: + if timestamp - lookup_es_key(last_occurence, self.ts_field) > self.rules['timeframe']: self.cardinality_cache[qk].pop(term) # Create a placeholder event for if a min_cardinality match occured