diff --git a/CHANGELOG.md b/CHANGELOG.md index f75a6837..933d78ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ## Other changes - Update setup.py & requirements.txt & requirements-dev.txt - [#1316](https://github.com/jertel/elastalert2/pull/1316) - @nsano-rururu - [Docs] Clarify how to reference query_key values in flatline alerts - [#1320](https://github.com/jertel/elastalert2/pull/1320) - @jertel +- Fix percentiles aggregation type in Spike Metric Aggregation rules - [#1323](https://github.com/jertel/elastalert2/pull/1323) - @jertel # 2.15.0 diff --git a/elastalert/ruletypes.py b/elastalert/ruletypes.py index 9200f2c4..47509f62 100644 --- a/elastalert/ruletypes.py +++ b/elastalert/ruletypes.py @@ -448,15 +448,16 @@ def get_spike_values(self, qk): extending ref/cur value retrieval logic for spike aggregations """ spike_check_type = self.rules.get('metric_agg_type') - if spike_check_type in [None, 'sum', 'value_count', 'cardinality', 'percentile']: - # default count logic is appropriate in all these cases - return self.ref_windows[qk].count(), self.cur_windows[qk].count() - elif spike_check_type == 'avg': + if spike_check_type == 'avg': return self.ref_windows[qk].mean(), self.cur_windows[qk].mean() elif spike_check_type == 'min': return self.ref_windows[qk].min(), self.cur_windows[qk].min() elif spike_check_type == 'max': return self.ref_windows[qk].max(), self.cur_windows[qk].max() + + # default count logic is appropriate in all other cases + return self.ref_windows[qk].count(), self.cur_windows[qk].count() + def clear_windows(self, qk, event): # Reset the state and prevent alerts until windows filled again diff --git a/tests/rules_test.py b/tests/rules_test.py index 137bab13..7d83a224 100644 --- a/tests/rules_test.py +++ b/tests/rules_test.py @@ -18,6 +18,7 @@ from elastalert.ruletypes import NewTermsRule from elastalert.ruletypes import PercentageMatchRule from elastalert.ruletypes import RuleType +from elastalert.ruletypes import SpikeMetricAggregationRule from elastalert.ruletypes import SpikeRule from elastalert.ruletypes import WhitelistRule from elastalert.util import dt_to_ts @@ -1400,3 +1401,29 @@ def test_comparerule_compare(): assert False except NotImplementedError: assert True + + +def test_spike_percentiles(): + rules = {'buffer_time': datetime.timedelta(minutes=5), + 'timeframe': datetime.timedelta(minutes=5), + 'timestamp_field': '@timestamp', + 'metric_agg_type': 'percentiles', + 'metric_agg_key': 'bytes', + 'percentile_range': 95, + 'spike_type': 'up', + 'spike_height': 1.5, + 'min_threshold': 0.0} + + rule = SpikeMetricAggregationRule(rules) + + payload1 = {"metric_bytes_percentiles": {"values": {"95.0": 0.0}}} + timestamp1 = datetime.datetime.now() - datetime.timedelta(minutes=600) + data1 = {timestamp1: payload1} + rule.add_aggregation_data(data1) + assert len(rule.matches) == 0 + + payload2 = {"metric_bytes_percentiles": {"values": {"95.0": 9879.0}}} + timestamp2 = datetime.datetime.now() + data2 = {timestamp2: payload2} + rule.add_aggregation_data(data2) + assert len(rule.matches) == 1