Skip to content

Commit 1334b61

Browse files
authored
Merge pull request Yelp#2593 from Yelp/fix_497
Allow run_every to be unique per rule
2 parents ec5d03b + bdbe144 commit 1334b61

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

elastalert/elastalert.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
from elasticsearch.exceptions import TransportError
2828

2929
from . import kibana
30-
from .kibana_discover import generate_kibana_discover_url
3130
from .alerts import DebugAlerter
3231
from .config import load_conf
3332
from .enhancements import DropMatchException
33+
from .kibana_discover import generate_kibana_discover_url
3434
from .ruletypes import FlatlineRule
3535
from .util import add_raw_postfix
3636
from .util import cronite_datetime_to_timestamp
@@ -1022,8 +1022,7 @@ def init_rule(self, new_rule, new=True):
10221022
'processed_hits',
10231023
'starttime',
10241024
'minimum_starttime',
1025-
'has_run_once',
1026-
'run_every']
1025+
'has_run_once']
10271026
for prop in copy_properties:
10281027
if prop not in rule:
10291028
continue
@@ -1467,8 +1466,8 @@ def send_alert(self, matches, rule, alert_time=None, retried=False):
14671466
# Compute top count keys
14681467
if rule.get('top_count_keys'):
14691468
for match in matches:
1470-
if 'query_key' in rule and rule['query_key'] in match:
1471-
qk = match[rule['query_key']]
1469+
if 'query_key' in rule:
1470+
qk = lookup_es_key(match, rule['query_key'])
14721471
else:
14731472
qk = None
14741473

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
'boto3>=1.4.4',
3434
'configparser>=3.5.0',
3535
'croniter>=0.3.16',
36-
'elasticsearch>=7.0.0',
36+
'elasticsearch==7.0.0',
3737
'envparse>=0.2.0',
3838
'exotel>=0.1.3',
3939
'jira>=2.0.0',

tests/base_test.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def test_init_rule(ea):
7575
ea.rules[0]['starttime'] = '2014-01-02T00:11:22'
7676
ea.rules[0]['processed_hits'] = ['abcdefg']
7777
new_rule = ea.init_rule(new_rule, False)
78-
for prop in ['starttime', 'agg_matches', 'current_aggregate_id', 'processed_hits', 'minimum_starttime']:
78+
for prop in ['starttime', 'agg_matches', 'current_aggregate_id', 'processed_hits', 'minimum_starttime', 'run_every']:
7979
assert new_rule[prop] == ea.rules[0][prop]
8080

8181
# Properties are fresh
@@ -84,6 +84,11 @@ def test_init_rule(ea):
8484
assert 'starttime' not in new_rule
8585
assert new_rule['processed_hits'] == {}
8686

87+
# Assert run_every is unique
88+
new_rule['run_every'] = datetime.timedelta(seconds=17)
89+
new_rule = ea.init_rule(new_rule, True)
90+
assert new_rule['run_every'] == datetime.timedelta(seconds=17)
91+
8792

8893
def test_query(ea):
8994
ea.thread_data.current_es.search.return_value = {'hits': {'total': 0, 'hits': []}}
@@ -989,17 +994,20 @@ def test_kibana_dashboard(ea):
989994
def test_rule_changes(ea):
990995
ea.rule_hashes = {'rules/rule1.yaml': 'ABC',
991996
'rules/rule2.yaml': 'DEF'}
992-
ea.rules = [ea.init_rule(rule, True) for rule in [{'rule_file': 'rules/rule1.yaml', 'name': 'rule1', 'filter': []},
993-
{'rule_file': 'rules/rule2.yaml', 'name': 'rule2', 'filter': []}]]
997+
run_every = datetime.timedelta(seconds=1)
998+
ea.rules = [ea.init_rule(rule, True) for rule in [{'rule_file': 'rules/rule1.yaml', 'name': 'rule1', 'filter': [],
999+
'run_every': run_every},
1000+
{'rule_file': 'rules/rule2.yaml', 'name': 'rule2', 'filter': [],
1001+
'run_every': run_every}]]
9941002
ea.rules[1]['processed_hits'] = ['save me']
9951003
new_hashes = {'rules/rule1.yaml': 'ABC',
9961004
'rules/rule3.yaml': 'XXX',
9971005
'rules/rule2.yaml': '!@#$'}
9981006

9991007
with mock.patch.object(ea.conf['rules_loader'], 'get_hashes') as mock_hashes:
10001008
with mock.patch.object(ea.conf['rules_loader'], 'load_configuration') as mock_load:
1001-
mock_load.side_effect = [{'filter': [], 'name': 'rule2', 'rule_file': 'rules/rule2.yaml'},
1002-
{'filter': [], 'name': 'rule3', 'rule_file': 'rules/rule3.yaml'}]
1009+
mock_load.side_effect = [{'filter': [], 'name': 'rule2', 'rule_file': 'rules/rule2.yaml', 'run_every': run_every},
1010+
{'filter': [], 'name': 'rule3', 'rule_file': 'rules/rule3.yaml', 'run_every': run_every}]
10031011
mock_hashes.return_value = new_hashes
10041012
ea.load_rule_changes()
10051013

@@ -1021,7 +1029,7 @@ def test_rule_changes(ea):
10211029
with mock.patch.object(ea.conf['rules_loader'], 'load_configuration') as mock_load:
10221030
with mock.patch.object(ea, 'send_notification_email') as mock_send:
10231031
mock_load.return_value = {'filter': [], 'name': 'rule3', 'new': 'stuff',
1024-
'rule_file': 'rules/rule4.yaml'}
1032+
'rule_file': 'rules/rule4.yaml', 'run_every': run_every}
10251033
mock_hashes.return_value = new_hashes
10261034
ea.load_rule_changes()
10271035
mock_send.assert_called_once_with(exception=mock.ANY, rule_file='rules/rule4.yaml')
@@ -1033,7 +1041,8 @@ def test_rule_changes(ea):
10331041
new_hashes.update({'rules/rule4.yaml': 'asdf'})
10341042
with mock.patch.object(ea.conf['rules_loader'], 'get_hashes') as mock_hashes:
10351043
with mock.patch.object(ea.conf['rules_loader'], 'load_configuration') as mock_load:
1036-
mock_load.return_value = {'filter': [], 'name': 'rule4', 'new': 'stuff', 'is_enabled': False, 'rule_file': 'rules/rule4.yaml'}
1044+
mock_load.return_value = {'filter': [], 'name': 'rule4', 'new': 'stuff', 'is_enabled': False,
1045+
'rule_file': 'rules/rule4.yaml', 'run_every': run_every}
10371046
mock_hashes.return_value = new_hashes
10381047
ea.load_rule_changes()
10391048
assert len(ea.rules) == 3
@@ -1044,7 +1053,8 @@ def test_rule_changes(ea):
10441053
new_hashes['rules/rule4.yaml'] = 'qwerty'
10451054
with mock.patch.object(ea.conf['rules_loader'], 'get_hashes') as mock_hashes:
10461055
with mock.patch.object(ea.conf['rules_loader'], 'load_configuration') as mock_load:
1047-
mock_load.return_value = {'filter': [], 'name': 'rule4', 'new': 'stuff', 'rule_file': 'rules/rule4.yaml'}
1056+
mock_load.return_value = {'filter': [], 'name': 'rule4', 'new': 'stuff', 'rule_file': 'rules/rule4.yaml',
1057+
'run_every': run_every}
10481058
mock_hashes.return_value = new_hashes
10491059
ea.load_rule_changes()
10501060
assert len(ea.rules) == 4
@@ -1053,7 +1063,8 @@ def test_rule_changes(ea):
10531063
new_hashes.pop('rules/rule4.yaml')
10541064
with mock.patch.object(ea.conf['rules_loader'], 'get_hashes') as mock_hashes:
10551065
with mock.patch.object(ea.conf['rules_loader'], 'load_configuration') as mock_load:
1056-
mock_load.return_value = {'filter': [], 'name': 'rule4', 'new': 'stuff', 'rule_file': 'rules/rule4.yaml'}
1066+
mock_load.return_value = {'filter': [], 'name': 'rule4', 'new': 'stuff', 'rule_file': 'rules/rule4.yaml',
1067+
'run_every': run_every}
10571068
mock_hashes.return_value = new_hashes
10581069
ea.load_rule_changes()
10591070
ea.scheduler.remove_job.assert_called_with(job_id='rule4')

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ def ea_sixsix():
202202
'index': 'idx',
203203
'filter': [],
204204
'include': ['@timestamp'],
205+
'run_every': datetime.timedelta(seconds=1),
205206
'aggregation': datetime.timedelta(0),
206207
'realert': datetime.timedelta(0),
207208
'processed_hits': {},

0 commit comments

Comments
 (0)