Check hash of message when determining if it is a new match
This commit is contained in:
parent
66596cda42
commit
0cbd2d8a6f
|
@ -10,6 +10,7 @@ except ImportError:
|
||||||
|
|
||||||
import orjson
|
import orjson
|
||||||
from asgiref.sync import async_to_sync
|
from asgiref.sync import async_to_sync
|
||||||
|
from siphashc import siphash
|
||||||
|
|
||||||
from core.lib.notify import sendmsg
|
from core.lib.notify import sendmsg
|
||||||
from core.lib.parsing import parse_index, parse_source
|
from core.lib.parsing import parse_index, parse_source
|
||||||
|
@ -205,8 +206,13 @@ class NotificationRuleData(object):
|
||||||
Store a match result.
|
Store a match result.
|
||||||
Accepts None for the index to set all indices.
|
Accepts None for the index to set all indices.
|
||||||
:param index: the index to store the match for, can be None
|
:param index: the index to store the match for, can be None
|
||||||
:param match: True or False, indicating if the rule matched
|
:param match: the object that matched
|
||||||
"""
|
"""
|
||||||
|
if match is not False:
|
||||||
|
# Dump match to JSON while sorting the keys
|
||||||
|
match_normalised = orjson.dumps(match, option=orjson.OPT_SORT_KEYS)
|
||||||
|
match = siphash(self.db.hash_key, match_normalised)
|
||||||
|
|
||||||
if self.object.match is None:
|
if self.object.match is None:
|
||||||
self.object.match = {}
|
self.object.match = {}
|
||||||
if not isinstance(self.object.match, dict):
|
if not isinstance(self.object.match, dict):
|
||||||
|
@ -220,7 +226,7 @@ class NotificationRuleData(object):
|
||||||
self.object.save()
|
self.object.save()
|
||||||
log.debug(f"Stored match: {index} - {match}")
|
log.debug(f"Stored match: {index} - {match}")
|
||||||
|
|
||||||
def get_match(self, index=None):
|
def get_match(self, index=None, match=None):
|
||||||
"""
|
"""
|
||||||
Get a match result for an index.
|
Get a match result for an index.
|
||||||
If the index is None, it will return True if any index has a match.
|
If the index is None, it will return True if any index has a match.
|
||||||
|
@ -237,6 +243,13 @@ class NotificationRuleData(object):
|
||||||
# Check if we have any matches on all indices
|
# Check if we have any matches on all indices
|
||||||
return any(self.object.match.values())
|
return any(self.object.match.values())
|
||||||
|
|
||||||
|
# Check if it's the same hash
|
||||||
|
if match is not None:
|
||||||
|
match_normalised = orjson.dumps(match, option=orjson.OPT_SORT_KEYS)
|
||||||
|
match = siphash(self.db.hash_key, match_normalised)
|
||||||
|
hash_matches = self.object.match.get(index) == match
|
||||||
|
return hash_matches
|
||||||
|
|
||||||
return self.object.match.get(index)
|
return self.object.match.get(index)
|
||||||
|
|
||||||
def format_aggs(self, aggs):
|
def format_aggs(self, aggs):
|
||||||
|
@ -268,13 +281,13 @@ class NotificationRuleData(object):
|
||||||
:param message: the message object that matched
|
:param message: the message object that matched
|
||||||
:param aggs: the aggregations that matched
|
:param aggs: the aggregations that matched
|
||||||
"""
|
"""
|
||||||
current_match = self.get_match(index)
|
current_match = self.get_match(index, message)
|
||||||
log.debug(f"Rule matched: {index} - current match: {current_match}")
|
log.debug(f"Rule matched: {index} - current match: {current_match}")
|
||||||
if current_match is False:
|
if current_match is False:
|
||||||
# Matched now, but not before
|
# Matched now, but not before
|
||||||
meta["matched"] = self.format_aggs(meta["aggs"])
|
meta["matched"] = self.format_aggs(meta["aggs"])
|
||||||
rule_notify(self.object, index, message, meta)
|
rule_notify(self.object, index, message, meta)
|
||||||
self.store_match(index, True)
|
self.store_match(index, message)
|
||||||
|
|
||||||
def rule_no_match(self, index=None):
|
def rule_no_match(self, index=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -203,7 +203,8 @@ class NotificationRule(models.Model):
|
||||||
Get the total number of matches for this rule.
|
Get the total number of matches for this rule.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.match, dict):
|
if isinstance(self.match, dict):
|
||||||
return f"{sum(list(self.match.values()))}/{len(self.match)}"
|
truthy_values = [x for x in self.match.values() if x is not False]
|
||||||
|
return f"{len(truthy_values)}/{len(self.match)}"
|
||||||
|
|
||||||
def get_notification_settings(self, check=True):
|
def get_notification_settings(self, check=True):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue