10
10
from slack_sdk .errors import SlackApiError
11
11
12
12
from sentry .constants import ISSUE_ALERTS_THREAD_DEFAULT
13
+ from sentry .integrations .messaging .metrics import (
14
+ MessagingInteractionEvent ,
15
+ MessagingInteractionType ,
16
+ )
13
17
from sentry .integrations .models .integration import Integration
14
18
from sentry .integrations .notifications import get_context
15
19
from sentry .integrations .repository import get_default_issue_alert_repository
25
29
SLACK_ACTIVITY_THREAD_SUCCESS_DATADOG_METRIC ,
26
30
SLACK_NOTIFY_RECIPIENT_FAILURE_DATADOG_METRIC ,
27
31
SLACK_NOTIFY_RECIPIENT_SUCCESS_DATADOG_METRIC ,
32
+ record_lifecycle_termination_level ,
28
33
)
29
34
from sentry .integrations .slack .sdk_client import SlackSdkClient
35
+ from sentry .integrations .slack .spec import SlackMessagingSpec
30
36
from sentry .integrations .slack .threads .activity_notifications import (
31
37
AssignedActivityNotification ,
32
38
ExternalIssueCreatedActivityNotification ,
@@ -182,12 +188,23 @@ def notify_all_threads_for_activity(self, activity: Activity) -> None:
182
188
slack_client = SlackSdkClient (integration_id = integration .id )
183
189
184
190
# Get all parent notifications, which will have the message identifier to use to reply in a thread
185
- parent_notifications = (
186
- self ._notification_message_repository .get_all_parent_notification_messages_by_filters (
191
+ with MessagingInteractionEvent (
192
+ interaction_type = MessagingInteractionType .GET_PARENT_NOTIFICATION ,
193
+ spec = SlackMessagingSpec (),
194
+ ).capture () as lifecycle :
195
+ lifecycle .add_extras (
196
+ {
197
+ "activity_id" : activity .id ,
198
+ "group_id" : activity .group .id ,
199
+ "project_id" : activity .project .id ,
200
+ }
201
+ )
202
+ parent_notifications = self ._notification_message_repository .get_all_parent_notification_messages_by_filters (
187
203
group_ids = [activity .group .id ],
188
204
project_ids = [activity .project .id ],
189
205
)
190
- )
206
+
207
+ # We don't wrap this in a lifecycle because _handle_parent_notification is already wrapped in a lifecycle
191
208
for parent_notification in parent_notifications :
192
209
try :
193
210
self ._handle_parent_notification (
@@ -196,6 +213,7 @@ def notify_all_threads_for_activity(self, activity: Activity) -> None:
196
213
client = slack_client ,
197
214
)
198
215
except Exception as err :
216
+ # TODO(iamrajjoshi): We can probably swallow this error once we audit the lifecycle
199
217
self ._logger .info (
200
218
"failed to send notification" ,
201
219
exc_info = err ,
@@ -254,25 +272,33 @@ def _handle_parent_notification(
254
272
"rule_action_uuid" : parent_notification .rule_action_uuid ,
255
273
}
256
274
257
- try :
258
- client .chat_postMessage (
259
- channel = channel_id ,
260
- thread_ts = parent_notification .message_identifier ,
261
- text = notification_to_send ,
262
- blocks = json_blocks ,
263
- )
264
- metrics .incr (SLACK_ACTIVITY_THREAD_SUCCESS_DATADOG_METRIC , sample_rate = 1.0 )
265
- except SlackApiError as e :
266
- self ._logger .info (
267
- "failed to post message to slack" ,
268
- extra = {"error" : str (e ), "blocks" : json_blocks , ** extra },
269
- )
270
- metrics .incr (
271
- SLACK_ACTIVITY_THREAD_FAILURE_DATADOG_METRIC ,
272
- sample_rate = 1.0 ,
273
- tags = {"ok" : e .response .get ("ok" , False ), "status" : e .response .status_code },
274
- )
275
- raise
275
+ with MessagingInteractionEvent (
276
+ interaction_type = MessagingInteractionType .SEND_ACTIVITY_NOTIFICATION ,
277
+ spec = SlackMessagingSpec (),
278
+ ).capture () as lifecycle :
279
+ try :
280
+ client .chat_postMessage (
281
+ channel = channel_id ,
282
+ thread_ts = parent_notification .message_identifier ,
283
+ text = notification_to_send ,
284
+ blocks = json_blocks ,
285
+ )
286
+ # TODO(iamrajjoshi): Remove this after we validate lifecycle
287
+ metrics .incr (SLACK_ACTIVITY_THREAD_SUCCESS_DATADOG_METRIC , sample_rate = 1.0 )
288
+ except SlackApiError as e :
289
+ # TODO(iamrajjoshi): Remove this after we validate lifecycle
290
+ self ._logger .info (
291
+ "failed to post message to slack" ,
292
+ extra = {"error" : str (e ), "blocks" : json_blocks , ** extra },
293
+ )
294
+ metrics .incr (
295
+ SLACK_ACTIVITY_THREAD_FAILURE_DATADOG_METRIC ,
296
+ sample_rate = 1.0 ,
297
+ tags = {"ok" : e .response .get ("ok" , False ), "status" : e .response .status_code },
298
+ )
299
+ lifecycle .add_extras ({"rule_action_uuid" : parent_notification .rule_action_uuid })
300
+ record_lifecycle_termination_level (lifecycle , e )
301
+ raise
276
302
277
303
def _get_notification_message_to_send (self , activity : Activity ) -> str | None :
278
304
"""
@@ -427,21 +453,32 @@ def send_message_to_slack_channel(
427
453
"""Execution of send_notification_as_slack."""
428
454
429
455
client = SlackSdkClient (integration_id = integration_id )
430
- try :
431
- client .chat_postMessage (
432
- blocks = str (payload .get ("blocks" , "" )),
433
- text = str (payload .get ("text" , "" )),
434
- channel = str (payload .get ("channel" , "" )),
435
- unfurl_links = False ,
436
- unfurl_media = False ,
437
- callback_id = str (payload .get ("callback_id" , "" )),
438
- )
439
- metrics .incr (SLACK_NOTIFY_RECIPIENT_SUCCESS_DATADOG_METRIC , sample_rate = 1.0 )
440
- except SlackApiError as e :
441
- extra = {"error" : str (e ), ** log_params }
442
- self ._logger .info (log_error_message , extra = extra )
443
- metrics .incr (
444
- SLACK_NOTIFY_RECIPIENT_FAILURE_DATADOG_METRIC ,
445
- sample_rate = 1.0 ,
446
- tags = {"ok" : e .response .get ("ok" , False ), "status" : e .response .status_code },
447
- )
456
+ with MessagingInteractionEvent (
457
+ interaction_type = MessagingInteractionType .SEND_GENERIC_NOTIFICATION ,
458
+ spec = SlackMessagingSpec (),
459
+ ).capture () as lifecycle :
460
+ try :
461
+ lifecycle .add_extras ({"integration_id" : integration_id })
462
+ client .chat_postMessage (
463
+ blocks = str (payload .get ("blocks" , "" )),
464
+ text = str (payload .get ("text" , "" )),
465
+ channel = str (payload .get ("channel" , "" )),
466
+ unfurl_links = False ,
467
+ unfurl_media = False ,
468
+ callback_id = str (payload .get ("callback_id" , "" )),
469
+ )
470
+ # TODO(iamrajjoshi): Remove this after we validate lifecycle
471
+ metrics .incr (SLACK_NOTIFY_RECIPIENT_SUCCESS_DATADOG_METRIC , sample_rate = 1.0 )
472
+ except SlackApiError as e :
473
+ # TODO(iamrajjoshi): Remove this after we validate lifecycle
474
+ extra = {"error" : str (e ), ** log_params }
475
+ self ._logger .info (log_error_message , extra = extra )
476
+ metrics .incr (
477
+ SLACK_NOTIFY_RECIPIENT_FAILURE_DATADOG_METRIC ,
478
+ sample_rate = 1.0 ,
479
+ tags = {"ok" : e .response .get ("ok" , False ), "status" : e .response .status_code },
480
+ )
481
+ lifecycle .add_extras (
482
+ {k : str (v ) for k , v in log_params .items () if isinstance (v , (int , str ))}
483
+ )
484
+ record_lifecycle_termination_level (lifecycle , e )
0 commit comments