Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'summary_table_max_rows' configuration option #508

Merged
merged 8 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

## New features
- [Alertmanager] Added support for Alertmanager - [#503](https://github.com/jertel/elastalert2/pull/503) - @nsano-rururu
- Add summary_table_max_rows optional configuration to limit rows in summary tables - [#508](https://github.com/jertel/elastalert2/pull/508) - @mdavyt92

## Other changes
- [Docs] Add exposed metrics documentation - [#498](https://github.com/jertel/elastalert2/pull/498) - @thisisxgp
Expand Down
7 changes: 7 additions & 0 deletions docs/source/ruletypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ For aggregations, there can sometimes be a large number of documents present in

The formatting style of the summary table can be switched between ``ascii`` (default) and ``markdown`` with parameter ``summary_table_type``. ``markdown`` might be the more suitable formatting for alerters supporting it like TheHive.

The maximum number of rows in the summary table can be limited with the parameter ``summary_table_max_rows``.

For example, if you wish to summarize the usernames and event_types that appear in the documents so that you can see the most relevant fields at a quick glance, you can set::

summary_table_fields:
Expand Down Expand Up @@ -721,6 +723,11 @@ summary_table_type

``summary_table_type``: Either ``ascii`` or ``markdown``. Select the table type to use for the aggregation summary. Defaults to ``ascii`` for the classical text based table.

summary_table_max_rows
^^^^^^^^^^^^^^^^^^^^^^

``summary_table_max_rows``: Limit the maximum number of rows that will be shown in the summary table.

summary_prefix
^^^^^^^^^^^^^^^^^^^^

Expand Down
11 changes: 11 additions & 0 deletions elastalert/alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from elastalert.util import EAException, lookup_es_key
from elastalert.yaml import read_yaml

from collections import Counter

class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
Expand Down Expand Up @@ -267,6 +268,11 @@ def get_aggregation_summary_text(self, matches):
else:
match_aggregation[key_tuple] = match_aggregation[key_tuple] + 1

# Limit number of rows
if 'summary_table_max_rows' in self.rule:
max_rows = self.rule['summary_table_max_rows']
match_aggregation = {k:v for k, v in Counter(match_aggregation).most_common(max_rows)}

# Type dependent table style
if summary_table_type == 'ascii':
text_table = Texttable(max_width=self.get_aggregation_summary_text__maximum_width())
Expand All @@ -292,6 +298,11 @@ def get_aggregation_summary_text(self, matches):
text += markdown_row + '| ' + str(count) + ' |\n'
text += '\n'

# max_rows message
if 'summary_table_max_rows' in self.rule:
text += f"Showing top {self.rule['summary_table_max_rows']} rows"
text += "\n"

# Type independent suffix
text += self.rule.get('summary_suffix', '')
return str(text)
Expand Down
7 changes: 7 additions & 0 deletions elastalert/schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,13 @@ properties:
replace_dots_in_field_names: {type: boolean}
scan_entire_timeframe: {type: boolean}

### summary table
summary_table_fields: {type: array, items: {type: string}}
summary_table_type: {type: string, enum: ['ascii', 'markdown']}
summary_table_max_rows: {type: number}
summary_prefix: {type: string}
summary_suffix: {type: string}

### Kibana Discover App Link
generate_kibana_discover_url: {type: boolean}
kibana_discover_app_url: {type: string, format: uri}
Expand Down
28 changes: 28 additions & 0 deletions tests/alerts_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,34 @@ def test_alert_aggregation_summary_default_table():
assert "| field_value | cde from match | 2 |" in summary_table


def test_alert_aggregation_summary_table_one_row():
rule = {
'name': 'test_rule',
'type': mock_rule(),
'owner': 'the_owner',
'priority': 2,
'alert_subject': 'A very long subject',
'aggregation': 1,
'summary_table_fields': ['field', 'abc'],
'summary_table_max_rows': 1,
}
matches = [
{'@timestamp': '2016-01-01', 'field': 'field_value', 'abc': 'abc from match', },
{'@timestamp': '2016-01-01', 'field': 'field_value', 'abc': 'abc from match', },
{'@timestamp': '2016-01-01', 'field': 'field_value', 'abc': 'abc from match', },
{'@timestamp': '2016-01-01', 'field': 'field_value', 'abc': 'cde from match', },
{'@timestamp': '2016-01-01', 'field': 'field_value', 'abc': 'cde from match', },
]
alert = Alerter(rule)
summary_table = str(alert.get_aggregation_summary_text(matches))
assert "+-------------+----------------+-------+" in summary_table
assert "| field | abc | count |" in summary_table
assert "+=============+================+=======+" in summary_table
assert "| field_value | abc from match | 3 |" in summary_table
assert "| field_value | cde from match | 2 |" not in summary_table
assert "Showing top 1 rows" in summary_table


def test_alert_aggregation_summary_table_suffix_prefix():
rule = {
'name': 'test_rule',
Expand Down