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

feat(aci milestone 3): ACI alert rule dual update helper #82982

Merged
merged 18 commits into from
Jan 16, 2025

Conversation

mifu67
Copy link
Contributor

@mifu67 mifu67 commented Jan 7, 2025

Add helper method to update the relevant ACI tables after updating an alert rule.
Also fixes some tests that weren't running because I named them incorrectly in my last PR 😅

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Jan 7, 2025
Copy link

codecov bot commented Jan 7, 2025

Codecov Report

Attention: Patch coverage is 92.85714% with 8 lines in your changes missing coverage. Please review.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ry/workflow_engine/migration_helpers/alert_rule.py 81.39% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master   #82982      +/-   ##
==========================================
+ Coverage   84.98%   87.65%   +2.66%     
==========================================
  Files        9487     9447      -40     
  Lines      538638   537897     -741     
  Branches    21200    21000     -200     
==========================================
+ Hits       457766   471490   +13724     
+ Misses      80430    66043   -14387     
+ Partials      442      364      -78     

@mifu67 mifu67 marked this pull request as ready for review January 13, 2025 22:26
@mifu67 mifu67 requested a review from a team as a code owner January 13, 2025 22:26
Copy link
Member

@cathteng cathteng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not familiar with the threshold type -> detector trigger update logic, but i do have some other questions

src/sentry/workflow_engine/migration_helpers/alert_rule.py Outdated Show resolved Hide resolved
@@ -374,6 +375,99 @@ def migrate_alert_rule(
)


def update_migrated_alert_rule(alert_rule: AlertRule, updated_fields: dict[str, Any]) -> (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will we update the workflow + actions here too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are dual updated with the AlertRuleTriggers/AlertRuleActions

src/sentry/workflow_engine/migration_helpers/alert_rule.py Outdated Show resolved Hide resolved
)
resolve_threshold_type = (
Condition.LESS_OR_EQUAL
if updated_fields["threshold_type"] == AlertRuleThresholdType.ABOVE.value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be resolve_threshold_type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the resolve threshold type is the opposite as the specified threshold type

Copy link
Member

@ceorourke ceorourke Jan 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just "less" and "greater" rather than with "or equal" for both - https://github.com/getsentry/sentry/blob/master/src/sentry/workflow_engine/migration_helpers/alert_rule.py#L208

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this logic is overall correct - it's inverting the logic type from the alert rule to create the resolution condition; for example: greater than 500 is Priority.HIGH would have a resolution threshold: less than or equal to 500 is Priority.RESOLVE -- and that means we don't need to do the +/- 0.000001 trick from before.

since the logic is always > or < in metric alerts, we can safely assume the equality operator should be applied for the inverse with resolution.

resolve_condition = data_conditions.filter(condition_result=DetectorPriorityLevel.OK)
resolve_condition.update(comparison=updated_fields["resolve_threshold"])

detector.update(**updated_detector_fields)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this fails, should the alert rule be updated? should updating the alert rule + the detector happen in a transaction so either both or neither is updated?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cathteng how is that done if you're updating 2 models? cause usually it's like with transaction.atomic(router.db_for_write(MyModel)):

@@ -374,6 +375,99 @@ def migrate_alert_rule(
)


def update_migrated_alert_rule(alert_rule: AlertRule, updated_fields: dict[str, Any]) -> (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how will you get these updated fields?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dual updated with the alert rule

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok because the tests make it seem like you're generating them manually so i wasn't sure

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, we're just testing the actual dual writing code separately so that the tests in test_logic.py can be cleaner (we also haven't hooked up the dual writing logic yet)

"""
metric_alert = self.create_alert_rule(threshold_type=AlertRuleThresholdType.ABOVE)
metric_alert = self.create_alert_rule(threshold_type=AlertRuleThresholdType.BELOW)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why has this switched?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default threshold type is ABOVE, so I changed it in this test to BELOW so we're not testing the same case twice. The test wasn't running because I named it incorrectly, so I missed that it was failing the test for the resolve threshold being GTE (happens when the threshold type is BELOW)

src/sentry/workflow_engine/migration_helpers/alert_rule.py Outdated Show resolved Hide resolved
src/sentry/workflow_engine/migration_helpers/alert_rule.py Outdated Show resolved Hide resolved
)
resolve_threshold_type = (
Condition.LESS_OR_EQUAL
if updated_fields["threshold_type"] == AlertRuleThresholdType.ABOVE.value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this logic is overall correct - it's inverting the logic type from the alert rule to create the resolution condition; for example: greater than 500 is Priority.HIGH would have a resolution threshold: less than or equal to 500 is Priority.RESOLVE -- and that means we don't need to do the +/- 0.000001 trick from before.

since the logic is always > or < in metric alerts, we can safely assume the equality operator should be applied for the inverse with resolution.

detector_state.update(active=False, state=DetectorPriorityLevel.OK)

# TODO: do we need to create an audit log entry here?
# do we need to return the detector's data conditions/DCG?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: audit log we probably should but I think we can punt that to another task as we'll need to create new audit log types entirely for the whole project

idk that we need to return the dc / dcg here since the user hitting this code path will be unaware of ACI as a whole, so it's not like we need to return this data in the api response. we will need to make a new serializer when we switch over though, so maybe then? I wouldn't worry about it right now though

Copy link
Member

@ceorourke ceorourke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm besides adding a transaction which I think would be nice

@mifu67 mifu67 enabled auto-merge (squash) January 16, 2025 21:33
@mifu67 mifu67 merged commit e1cf8b5 into master Jan 16, 2025
49 checks passed
@mifu67 mifu67 deleted the mifu67/aci/dual-update-helpers branch January 16, 2025 22:00
andrewshie-sentry pushed a commit that referenced this pull request Jan 22, 2025
Add helper method to update the relevant ACI tables after updating an
alert rule.
Also fixes some tests that weren't running because I named them
incorrectly in my last PR 😅

---------

Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
@mifu67 mifu67 restored the mifu67/aci/dual-update-helpers branch January 23, 2025 19:20
@mifu67 mifu67 deleted the mifu67/aci/dual-update-helpers branch January 23, 2025 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scope: Backend Automatically applied to PRs that change backend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants