-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(workflow_engine): Add way to hook logic into
Detector
(#78540)
This adds some ways that we can hook custom logic into the detector. Looking at the options, it feels like splitting this logic into different handlers makes sense. Doesn't have to be a function - we can implement classes so that we can share logic. <!-- Describe your PR here. -->
- Loading branch information
Showing
8 changed files
with
319 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from dataclasses import dataclass | ||
|
||
from sentry.incidents.utils.types import QuerySubscriptionUpdate | ||
from sentry.issues.grouptype import GroupCategory, GroupType | ||
from sentry.ratelimits.sliding_windows import Quota | ||
from sentry.types.group import PriorityLevel | ||
from sentry.workflow_engine.models import DataPacket | ||
from sentry.workflow_engine.models.detector import DetectorEvaluationResult, DetectorHandler | ||
|
||
|
||
# TODO: This will be a stateful detector when we build that abstraction | ||
class MetricAlertDetectorHandler(DetectorHandler[QuerySubscriptionUpdate]): | ||
def evaluate( | ||
self, data_packet: DataPacket[QuerySubscriptionUpdate] | ||
) -> list[DetectorEvaluationResult]: | ||
# TODO: Implement | ||
return [] | ||
|
||
|
||
# Example GroupType and detector handler for metric alerts. We don't create these issues yet, but we'll use something | ||
# like these when we're sending issues as alerts | ||
@dataclass(frozen=True) | ||
class MetricAlertFire(GroupType): | ||
type_id = 8001 | ||
slug = "metric_alert_fire" | ||
description = "Metric alert fired" | ||
category = GroupCategory.METRIC_ALERT.value | ||
creation_quota = Quota(3600, 60, 100) | ||
default_priority = PriorityLevel.HIGH | ||
enable_auto_resolve = False | ||
enable_escalation_detection = False | ||
detector_handler = MetricAlertDetectorHandler |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import logging | ||
|
||
from sentry.workflow_engine.models import Detector | ||
from sentry.workflow_engine.models.data_source import DataPacket | ||
from sentry.workflow_engine.models.detector import DetectorEvaluationResult | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def process_detectors( | ||
data_packet: DataPacket, detectors: list[Detector] | ||
) -> list[tuple[Detector, list[DetectorEvaluationResult]]]: | ||
results = [] | ||
for detector in detectors: | ||
handler = detector.detector_handler | ||
if not handler: | ||
continue | ||
detector_results = handler.evaluate(data_packet) | ||
detector_group_keys = set() | ||
for result in detector_results: | ||
if result.state_update_data: | ||
if result.state_update_data.group_key in detector_group_keys: | ||
# This shouldn't happen - log an error and continue on, but we should investigate this. | ||
logger.error( | ||
"Duplicate detector state group keys found", | ||
extra={ | ||
"detector_id": detector.id, | ||
"group_key": result.state_update_data.group_key, | ||
}, | ||
) | ||
detector_group_keys.add(result.state_update_data.group_key) | ||
|
||
if detector_results: | ||
results.append((detector, detector_results)) | ||
|
||
return results |
Oops, something went wrong.