Skip to content

Commit bb30d49

Browse files
authored
feat(eap): Enable deletion from EAP by default, with a killswitch option (#102808)
Follow-up to #101385 / [ID-997](https://linear.app/getsentry/issue/ID-997/set-up-double-deletions-with-eap). Resolves [ID-1108](https://linear.app/getsentry/issue/ID-1108/flip-on-eap-double-deletion-by-default). The `DeleteTraceItems` endpoint ([protobuf definition](https://github.com/getsentry/sentry-protos/blob/main/proto/sentry_protos/snuba/v1/endpoint_delete_trace_items.proto)) is currently a no-op for deletion-by-attribute (getsentry/snuba#7535), so we're flipping deletion on by default. The `eventstream.eap.deletion-enabled` option provides a killswitch in case we need it.
1 parent 9254c18 commit bb30d49

File tree

3 files changed

+35
-44
lines changed

3 files changed

+35
-44
lines changed

src/sentry/deletions/tasks/nodestore.py

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -215,38 +215,33 @@ def delete_events_from_eap(
215215
group_ids: Sequence[int],
216216
dataset: Dataset,
217217
) -> None:
218-
eap_deletion_allowlist = options.get("eventstream.eap.deletion_enabled.organization_allowlist")
219-
if organization_id not in eap_deletion_allowlist:
218+
if not options.get("eventstream.eap.deletion-enabled"):
220219
return
221220

222221
try:
223-
response = delete_groups_from_eap_rpc(
222+
delete_groups_from_eap_rpc(
224223
organization_id=organization_id,
225224
project_id=project_id,
226225
group_ids=group_ids,
227226
referrer="deletions.group.eap",
228227
)
229-
logger.info(
230-
"eap.delete_groups.completed",
231-
extra={
232-
"organization_id": organization_id,
233-
"project_id": project_id,
234-
"group_count": len(group_ids),
235-
"matching_items_count": response.matching_items_count,
236-
},
228+
metrics.incr(
229+
"deletions.group.eap.success",
230+
tags={"dataset": dataset.value},
231+
sample_rate=1.0,
237232
)
238-
except Exception as e:
233+
except Exception:
239234
logger.exception(
240-
"eap.delete_groups.failed",
235+
"Failed to delete groups from EAP",
241236
extra={
242237
"organization_id": organization_id,
243238
"project_id": project_id,
244239
"group_ids": group_ids[:10],
245-
"error": str(e),
240+
"dataset": dataset.value,
246241
},
247242
)
248243
metrics.incr(
249-
"deletions.eap.failed",
244+
"deletions.group.eap.failure",
250245
tags={"dataset": dataset.value},
251246
sample_rate=1.0,
252247
)

src/sentry/options/defaults.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,12 +3598,12 @@
35983598
flags=FLAG_ALLOW_EMPTY | FLAG_AUTOMATOR_MODIFIABLE,
35993599
)
36003600

3601-
# The allowlist of organization IDs for which deletion from EAP is enabled.
3601+
# Controls whether deletion from EAP is enabled.
36023602
register(
3603-
"eventstream.eap.deletion_enabled.organization_allowlist",
3604-
type=Sequence,
3605-
default=[],
3606-
flags=FLAG_ALLOW_EMPTY | FLAG_AUTOMATOR_MODIFIABLE,
3603+
"eventstream.eap.deletion-enabled",
3604+
type=Bool,
3605+
default=True,
3606+
flags=FLAG_AUTOMATOR_MODIFIABLE,
36073607
)
36083608

36093609
# Send logs for sentry app webhooks sent. Should only be enabled for debugging a specific app or installation.

tests/sentry/eventstream/test_eap.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,9 @@ def test_deletion_with_error_dataset(self, mock_rpc):
2323
matching_items_count=150,
2424
)
2525

26-
with self.options(
27-
{"eventstream.eap.deletion_enabled.organization_allowlist": [self.organization_id]}
28-
):
29-
delete_events_from_eap(
30-
self.organization_id, self.project_id, self.group_ids, Dataset.Events
31-
)
32-
26+
delete_events_from_eap(
27+
self.organization_id, self.project_id, self.group_ids, Dataset.Events
28+
)
3329
assert mock_rpc.call_count == 1
3430

3531
request = mock_rpc.call_args[0][0]
@@ -50,29 +46,17 @@ def test_multiple_group_ids(self, mock_rpc):
5046

5147
many_group_ids = [10, 20, 30, 40, 50]
5248

53-
with self.options(
54-
{"eventstream.eap.deletion_enabled.organization_allowlist": [self.organization_id]}
55-
):
56-
delete_events_from_eap(
57-
self.organization_id, self.project_id, many_group_ids, Dataset.Events
58-
)
49+
delete_events_from_eap(
50+
self.organization_id, self.project_id, many_group_ids, Dataset.Events
51+
)
5952

6053
request = mock_rpc.call_args[0][0]
6154
group_filter = request.filters[0].filter.and_filter.filters[1]
6255
assert list(group_filter.comparison_filter.value.val_int_array.values) == many_group_ids
6356

6457
@patch("sentry.eventstream.eap.snuba_rpc.rpc")
65-
def test_organization_not_in_allowlist_skips_deletion(self, mock_rpc):
66-
with self.options({"eventstream.eap.deletion_enabled.organization_allowlist": [456, 789]}):
67-
delete_events_from_eap(
68-
self.organization_id, self.project_id, self.group_ids, Dataset.Events
69-
)
70-
71-
mock_rpc.assert_not_called()
72-
73-
@patch("sentry.eventstream.eap.snuba_rpc.rpc")
74-
def test_empty_allowlist_skips_deletion(self, mock_rpc):
75-
with self.options({"eventstream.eap.deletion_enabled.organization_allowlist": []}):
58+
def test_eap_deletion_disabled_skips_deletion(self, mock_rpc):
59+
with self.options({"eventstream.eap.deletion-enabled": False}):
7660
delete_events_from_eap(
7761
self.organization_id, self.project_id, self.group_ids, Dataset.Events
7862
)
@@ -86,3 +70,15 @@ def test_empty_group_ids_raises_error(self):
8670
project_id=self.project_id,
8771
group_ids=[],
8872
)
73+
74+
@patch("sentry.eventstream.eap.snuba_rpc.rpc")
75+
def test_exception_does_not_propagate(self, mock_rpc):
76+
mock_rpc.side_effect = Exception("RPC connection failed")
77+
78+
# Should not raise - exception should be caught
79+
try:
80+
delete_events_from_eap(
81+
self.organization_id, self.project_id, self.group_ids, Dataset.Events
82+
)
83+
except Exception:
84+
pytest.fail("Exception should have been caught and not propagated")

0 commit comments

Comments
 (0)