Skip to content

Commit

Permalink
[Alerts] Add support for summary message (#5590)
Browse files Browse the repository at this point in the history
Signed-off-by: Yan Burman <yanburman@users.noreply.github.com>
  • Loading branch information
yanburman committed May 21, 2024
1 parent 49d0656 commit e993ee2
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 6 deletions.
6 changes: 4 additions & 2 deletions mlrun/common/schemas/alert.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ class AlertConfig(pydantic.BaseModel):
pydantic.Field(
description=(
"String to be sent in the notifications generated."
"e.g. 'Model {{ $project }}/{{ $entity }} is drifting.'"
"e.g. 'Model {{project}}/{{entity}} is drifting.'"
"Supported variables: project, entity, name"
)
),
]
Expand Down Expand Up @@ -162,7 +163,8 @@ class AlertTemplate(

# AlertConfig fields that are pre-defined
description: Optional[str] = (
"String to be sent in the generated notifications e.g. 'Model {{ $project }}/{{ $entity }} is drifting.'"
"String to be sent in the generated notifications e.g. 'Model {{project}}/{{entity}} is drifting.'"
"See AlertConfig.summary description"
)
severity: AlertSeverity
trigger: AlertTrigger
Expand Down
9 changes: 9 additions & 0 deletions mlrun/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1603,3 +1603,12 @@ def validate_component_version_compatibility(
if parsed_current_version < parsed_min_version:
return False
return True


def format_alert_summary(
alert: mlrun.common.schemas.AlertConfig, event_data: mlrun.common.schemas.Event
) -> str:
result = alert.summary.replace("{{project}}", alert.project)
result = result.replace("{{name}}", alert.name)
result = result.replace("{{entity}}", event_data.entity.ids[0])
return result
8 changes: 8 additions & 0 deletions mlrun/utils/notifications/notification/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ def _get_alert_fields(
self._get_slack_row(f"*Project:*\n{alert.project}"),
self._get_slack_row(f"*UID:*\n{event_data.entity.ids[0]}"),
]

if alert.summary:
line.append(
self._get_slack_row(
f"*Summary:*\n{mlrun.utils.helpers.format_alert_summary(alert, event_data)}"
)
)

if event_data.value_dict:
data_lines = []
for key, value in event_data.value_dict.items():
Expand Down
8 changes: 4 additions & 4 deletions tests/integration/sdk_api/alerts/test_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_alert_operations(self):
"kind": alert_objects.EventEntityKind.MODEL,
"project": project_name,
},
"summary": "Model {{ $project }}/{{ $entity }} is drifting.",
"summary": "Model {{project}}/{{entity}} is drifting.",
"event_name": alert_objects.EventKind.DRIFT_DETECTED,
"state": alert_objects.AlertActiveState.INACTIVE,
}
Expand All @@ -48,7 +48,7 @@ def test_alert_operations(self):
"kind": alert_objects.EventEntityKind.JOB,
"project": project_name,
},
"summary": "Job {{ $project }}/{{ $entity }} failed.",
"summary": "Job {{project}}/{{entity}} failed.",
"event_name": alert_objects.EventKind.FAILED,
"state": alert_objects.AlertActiveState.INACTIVE,
"count": 3,
Expand Down Expand Up @@ -145,7 +145,7 @@ def test_alert_after_project_deletion(self):
project_name = "my-new-project"
event_name = alert_objects.EventKind.DRIFT_DETECTED
alert_name = "drift"
alert_summary = "Model {{ $project }}/{{ $entity }} is drifting."
alert_summary = "Model {{project}}/{{entity}} is drifting."
alert_entity_kind = alert_objects.EventEntityKind.MODEL
alert_entity_project = project_name

Expand Down Expand Up @@ -455,7 +455,7 @@ def _modify_alert_test(self, project_name, alert1, alert_name, new_event_name):
)

# modify alert with no errors
new_summary = "Aye ya yay {{ $project }}"
new_summary = "Aye ya yay {{project}}"
modified_alert = self._modify_alert(
project_name,
alert_name,
Expand Down
90 changes: 90 additions & 0 deletions tests/utils/test_alerts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Copyright 2024 Iguazio
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#


import pytest

import mlrun.common.schemas
import mlrun.common.schemas.alert as alert_objects
import mlrun.utils.helpers


@pytest.mark.parametrize(
"summary, project, alert_name, entity_id, expected_str",
[
(
"Model {{project}}/{{entity}} is drifting.",
"my-project",
None,
"123",
"Model my-project/123 is drifting.",
),
(
"Alert {{name}}: Model {{project}}/{{entity}} is drifting.",
"my-project123",
"alert",
"ddd",
"Alert alert: Model my-project123/ddd is drifting.",
),
(
"Model is drifting.",
None,
None,
None,
"Model is drifting.",
),
],
)
def test_summary_formatter(summary, project, alert_name, entity_id, expected_str):
notification = mlrun.common.schemas.Notification(
kind="slack",
name="slack_drift",
message="Ay caramba!",
severity="warning",
when=["now"],
secret_params={
"webhook": "https://hooks.slack.com/services/",
},
condition="oops",
)

event_kind = alert_objects.EventKind.DRIFT_SUSPECTED
entity_kind = alert_objects.EventEntityKind.MODEL

project = "my-project" if project is None else project
alert_name = "my-alert" if alert_name is None else alert_name
entity_id = "123" if entity_id is None else entity_id

alert = mlrun.common.schemas.AlertConfig(
project=project,
name=alert_name,
summary=summary,
severity=alert_objects.AlertSeverity.MEDIUM,
entities=alert_objects.EventEntities(
kind=entity_kind,
project=project,
ids=[entity_id],
),
trigger=alert_objects.AlertTrigger(events=[event_kind]),
notifications=[alert_objects.AlertNotification(notification=notification)],
)
alert_data = mlrun.common.schemas.Event(
kind=event_kind,
entity=alert_objects.EventEntities(
kind=entity_kind, project=project, ids=[entity_id]
),
)
result = mlrun.utils.helpers.format_alert_summary(alert, alert_data)
assert result == expected_str

0 comments on commit e993ee2

Please sign in to comment.