From f473bd509ba4a1a12ae259eaa3ef15a2b241eeb1 Mon Sep 17 00:00:00 2001 From: Robert Szefler Date: Tue, 9 Apr 2024 18:31:11 +0200 Subject: [PATCH] misc fixes --- src/robusta/core/sinks/sink_base.py | 4 ++-- src/robusta/core/sinks/slack/slack_sink.py | 10 ++++++---- src/robusta/integrations/slack/sender.py | 19 ++++++++++++++----- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/robusta/core/sinks/sink_base.py b/src/robusta/core/sinks/sink_base.py index a114529af..d53eb8a6b 100644 --- a/src/robusta/core/sinks/sink_base.py +++ b/src/robusta/core/sinks/sink_base.py @@ -54,10 +54,10 @@ def __init__(self, sink_params: SinkBaseParams, registry): "grouping.notification_mode.summary.by" ) key = keys[0] - if key not in ["labels", "attributes"]: + if key not in ["labels", "annotations"]: raise ValueError( f"Sink configuration: grouping.notification_mode.summary.by.{key} is invalid " - "(only labels/attributes allowed)" + "(only labels/annotations allowed)" ) for label_or_attr_name in attr[key]: self.finding_summary_header.append(f"{key[:-1]}:{label_or_attr_name}") diff --git a/src/robusta/core/sinks/slack/slack_sink.py b/src/robusta/core/sinks/slack/slack_sink.py index aa5e8a5b8..782ad9364 100644 --- a/src/robusta/core/sinks/slack/slack_sink.py +++ b/src/robusta/core/sinks/slack/slack_sink.py @@ -53,6 +53,9 @@ def handle_notification_grouping(self, finding: Finding, platform_enabled: bool) return if self.grouping_summary_mode: + # TODO summary_classification_header could be precomputed just as + # self.finding_summary_header is in SinkBase.__init__. This would + # simplify classify_finding quite a bit. summary_classification, summary_classification_header = self.classify_finding( finding_data, self.params.grouping.notification_mode.summary.by ) @@ -72,7 +75,7 @@ def handle_notification_grouping(self, finding: Finding, platform_enabled: bool) # Create the first Slack message if self.grouping_summary_mode: initial_counts = (1, 0) if status == FindingStatus.FIRING else (0, 1) - initial_counts_table = {group_by_classification: initial_counts} + initial_counts_table = {summary_classification: initial_counts} self.finding_summary_counts[group_by_classification] = initial_counts_table logging.info("Creating first Slack summarised thread") slack_thread_ts = self.slack_sender.send_summary_message( @@ -101,10 +104,9 @@ def classify_finding(self, finding_data: Dict, attributes: List) -> Tuple[Tuple[ logging.warning(f"Notification grouping: tried to group on non-existent attribute {attr}") continue values += (finding_data.get(attr),) - descriptions.append(f"{attr}={finding_data.get(attr)}") + descriptions.append(f"{'event_name' if attr=='identifier' else attr}={finding_data.get(attr)}") elif isinstance(attr, dict): - if list(attr.keys()) not in [["labels"], ["attributes"]]: - logging.warning(f"Notification grouping: tried to group on non-existent attribute(s) {attr}") + # This is typically labels and annotations top_level_attr_name = list(attr.keys())[0] values += tuple( finding_data.get(top_level_attr_name, {}).get(subitem_name) diff --git a/src/robusta/integrations/slack/sender.py b/src/robusta/integrations/slack/sender.py index c67a42a2c..4c33e040f 100644 --- a/src/robusta/integrations/slack/sender.py +++ b/src/robusta/integrations/slack/sender.py @@ -391,7 +391,7 @@ def send_summary_message( self, summary_classification_header: List[str], finding_summary_header: List[str], - summary_table: Dict[tuple, Tuple[int, int]], + summary_table: Dict[Tuple[str], Tuple[int, int]], sink_params: SlackSinkParams, platform_enabled: bool, msg_ts: str = None # message identifier (for updates) @@ -400,14 +400,23 @@ def send_summary_message( firing/resolved and a header describing the event group that this information concerns.""" logging.warning(f"XXX send_summary_table {summary_classification_header=} {finding_summary_header=} {summary_table=}") - blocks = [ - self.__to_slack(MarkdownBlock("👀 Summary for: " + ", ".join(summary_classification_header)), - ] + rows = [] + for key, value in summary_table: + # key is a tuple of attribute names; value is a 2-tuple with the number of firing and resolved events + row = key + value + rows.append(row) + + table_block = TableBlock( + headers=finding_summary_header + ["Firing", "Resolved"], + rows=rows + ) + blocks = self.__to_slack(MarkdownBlock("👀 Summary for: " + ", ".join(summary_classification_header))) + blocks.extend(self.__to_slack(table_block)) try: resp = self.slack_client.chat_postMessage( # TODO: for the purpose of the summary, we pretend labels and annotations are empty. Is this okay? channel=sink_params.get_slack_channel(self.cluster_name, {}, {}), - # text="A summary message", + text="Summary for: " + ", ".join(summary_classification_header), blocks=blocks, display_as_bot=True, )