def test_metric_aggregation_complex_query_key_bucket_interval(): rules = {'buffer_time': datetime.timedelta(minutes=5), 'timestamp_field': '@timestamp', 'metric_agg_type': 'avg', 'metric_agg_key': 'cpu_pct', 'bucket_interval': {'minutes': 1}, 'bucket_interval_timedelta': datetime.timedelta(minutes=1), 'compound_query_key': ['qk', 'sub_qk'], 'query_key': 'qk,sub_qk', 'max_threshold': 0.8} # Quoted from https://elastalert.readthedocs.io/en/latest/ruletypes.html#metric-aggregation # bucket_interval: If present this will divide the metric calculation window into bucket_interval sized segments. # The metric value will be calculated and evaluated against the threshold(s) for each segment. interval_aggs = {"interval_aggs": {"buckets": [ {"metric_cpu_pct_avg": {"value": 0.91}, "key": "1617156690000"}, {"metric_cpu_pct_avg": {"value": 0.89}, "key": "1617156750000"}, {"metric_cpu_pct_avg": {"value": 0.78}, "key": "1617156810000"}, {"metric_cpu_pct_avg": {"value": 0.85}, "key": "1617156870000"}, {"metric_cpu_pct_avg": {"value": 0.86}, "key": "1617156930000"}, ]}, "key": "sub_qk_val1"} query = {"bucket_aggs": {"buckets": [ interval_aggs ]}, "key": "qk_val"} rule = MetricAggregationRule(rules) rule.check_matches(datetime.datetime.now(), 'qk_val', query) assert len(rule.matches) == 4 assert rule.matches[0]['qk'] == 'qk_val' assert rule.matches[1]['qk'] == 'qk_val' assert rule.matches[0]['sub_qk'] == 'sub_qk_val1' assert rule.matches[1]['sub_qk'] == 'sub_qk_val1'
def test_metric_aggregation(): rules = { 'buffer_time': datetime.timedelta(minutes=5), 'timestamp_field': '@timestamp', 'metric_agg_type': 'avg', 'metric_agg_key': 'cpu_pct' } # Check threshold logic with pytest.raises(EAException): rule = MetricAggregationRule(rules) rules['min_threshold'] = 0.1 rules['max_threshold'] = 0.8 rule = MetricAggregationRule(rules) assert rule.rules['aggregation_query_element'] == { 'metric_cpu_pct_avg': { 'avg': { 'field': 'cpu_pct' } } } assert rule.crossed_thresholds(None) is False assert rule.crossed_thresholds(0.09) is True assert rule.crossed_thresholds(0.10) is False assert rule.crossed_thresholds(0.79) is False assert rule.crossed_thresholds(0.81) is True rule.check_matches(datetime.datetime.now(), None, {'metric_cpu_pct_avg': { 'value': None }}) rule.check_matches(datetime.datetime.now(), None, {'metric_cpu_pct_avg': { 'value': 0.5 }}) assert len(rule.matches) == 0 rule.check_matches(datetime.datetime.now(), None, {'metric_cpu_pct_avg': { 'value': 0.05 }}) rule.check_matches(datetime.datetime.now(), None, {'metric_cpu_pct_avg': { 'value': 0.95 }}) assert len(rule.matches) == 2 rules['query_key'] = 'qk' rule = MetricAggregationRule(rules) rule.check_matches(datetime.datetime.now(), 'qk_val', {'metric_cpu_pct_avg': { 'value': 0.95 }}) assert rule.matches[0]['qk'] == 'qk_val'
def test_metric_aggregation(): rules = {'buffer_time': datetime.timedelta(minutes=5), 'timestamp_field': '@timestamp', 'metric_agg_type': 'avg', 'metric_agg_key': 'cpu_pct'} # Check threshold logic with pytest.raises(EAException): rule = MetricAggregationRule(rules) rules['min_threshold'] = 0.1 rules['max_threshold'] = 0.8 rule = MetricAggregationRule(rules) assert rule.rules['aggregation_query_element'] == {'cpu_pct_avg': {'avg': {'field': 'cpu_pct'}}} assert rule.crossed_thresholds(None) is False assert rule.crossed_thresholds(0.09) is True assert rule.crossed_thresholds(0.10) is False assert rule.crossed_thresholds(0.79) is False assert rule.crossed_thresholds(0.81) is True rule.check_matches(datetime.datetime.now(), None, {'cpu_pct_avg': {'value': None}}) rule.check_matches(datetime.datetime.now(), None, {'cpu_pct_avg': {'value': 0.5}}) assert len(rule.matches) == 0 rule.check_matches(datetime.datetime.now(), None, {'cpu_pct_avg': {'value': 0.05}}) rule.check_matches(datetime.datetime.now(), None, {'cpu_pct_avg': {'value': 0.95}}) assert len(rule.matches) == 2 rules['query_key'] = 'qk' rule = MetricAggregationRule(rules) rule.check_matches(datetime.datetime.now(), 'qk_val', {'cpu_pct_avg': {'value': 0.95}}) assert rule.matches[0]['qk'] == 'qk_val'
def test_metric_aggregation_complex_query_key(): rules = { 'buffer_time': datetime.timedelta(minutes=5), 'timestamp_field': '@timestamp', 'metric_agg_type': 'avg', 'metric_agg_key': 'cpu_pct', 'compound_query_key': ['qk', 'sub_qk'], 'query_key': 'qk,sub_qk', 'max_threshold': 0.8 } query = { "bucket_aggs": { "buckets": [{ "metric_cpu_pct_avg": { "value": 0.91 }, "key": "sub_qk_val1" }, { "metric_cpu_pct_avg": { "value": 0.95 }, "key": "sub_qk_val2" }, { "metric_cpu_pct_avg": { "value": 0.89 }, "key": "sub_qk_val3" }] }, "key": "qk_val" } rule = MetricAggregationRule(rules) rule.check_matches(datetime.datetime.now(), 'qk_val', query) assert len(rule.matches) == 3 assert rule.matches[0]['qk'] == 'qk_val' assert rule.matches[1]['qk'] == 'qk_val' assert rule.matches[0]['sub_qk'] == 'sub_qk_val1' assert rule.matches[1]['sub_qk'] == 'sub_qk_val2'
def test_metric_aggregation_complex_query_key(): rules = {'buffer_time': datetime.timedelta(minutes=5), 'timestamp_field': '@timestamp', 'metric_agg_type': 'avg', 'metric_agg_key': 'cpu_pct', 'compound_query_key': ['qk', 'sub_qk'], 'query_key': 'qk,sub_qk', 'max_threshold': 0.8} query = {"bucket_aggs": {"buckets": [ {"cpu_pct_avg": {"value": 0.91}, "key": "sub_qk_val1"}, {"cpu_pct_avg": {"value": 0.95}, "key": "sub_qk_val2"}, {"cpu_pct_avg": {"value": 0.89}, "key": "sub_qk_val3"}] }, "key": "qk_val"} rule = MetricAggregationRule(rules) rule.check_matches(datetime.datetime.now(), 'qk_val', query) assert len(rule.matches) == 3 assert rule.matches[0]['qk'] == 'qk_val' assert rule.matches[1]['qk'] == 'qk_val' assert rule.matches[0]['sub_qk'] == 'sub_qk_val1' assert rule.matches[1]['sub_qk'] == 'sub_qk_val2'