@@ -270,25 +270,49 @@ def _unpack_organization(alert_rule: AlertRule) -> Organization:
270270 return organization
271271
272272
273- def _build_incident_query_builder (
274- incident : Incident ,
275- entity_subscription : EntitySubscription ,
276- start : datetime | None = None ,
277- end : datetime | None = None ,
278- windowed_stats : bool = False ,
273+ @dataclass
274+ class BaseMetricIssueQueryParams :
275+ snuba_query : SnubaQuery
276+ date_started : datetime
277+ current_end_date : datetime
278+ organization : Organization
279+
280+
281+ @dataclass
282+ class CalculateOpenPeriodTimeRangeParams (BaseMetricIssueQueryParams ):
283+ start_arg : datetime | None = None
284+ end_arg : datetime | None = None
285+
286+
287+ @dataclass
288+ class BuildMetricQueryBuilderParams (BaseMetricIssueQueryParams ):
289+ project_ids : list [int ]
290+ entity_subscription : EntitySubscription
291+ start_arg : datetime | None = None
292+ end_arg : datetime | None = None
293+
294+
295+ def _build_metric_query_builder (
296+ params : BuildMetricQueryBuilderParams ,
279297) -> BaseQueryBuilder :
280- snuba_query = _unpack_snuba_query (incident .alert_rule )
281- start , end = _calculate_incident_time_range (incident , start , end , windowed_stats = windowed_stats )
282- project_ids = list (
283- IncidentProject .objects .filter (incident = incident ).values_list ("project_id" , flat = True )
298+ start , end = _calculate_open_period_time_range (
299+ CalculateOpenPeriodTimeRangeParams (
300+ snuba_query = params .snuba_query ,
301+ date_started = params .date_started ,
302+ current_end_date = params .current_end_date ,
303+ organization = params .organization ,
304+ start_arg = params .start_arg ,
305+ end_arg = params .end_arg ,
306+ )
284307 )
285- query_builder = entity_subscription .build_query_builder (
286- query = snuba_query .query ,
287- project_ids = project_ids ,
288- environment = snuba_query .environment ,
308+
309+ query_builder = params .entity_subscription .build_query_builder (
310+ query = params .snuba_query .query ,
311+ project_ids = params .project_ids ,
312+ environment = params .snuba_query .environment ,
289313 params = {
290- "organization_id" : incident . organization_id ,
291- "project_id" : project_ids ,
314+ "organization_id" : params . organization . id ,
315+ "project_id" : params . project_ids ,
292316 "start" : start ,
293317 "end" : end ,
294318 },
@@ -309,37 +333,19 @@ def _build_incident_query_builder(
309333 return query_builder
310334
311335
312- def _calculate_incident_time_range (
313- incident : Incident ,
314- start_arg : datetime | None = None ,
315- end_arg : datetime | None = None ,
316- windowed_stats : bool = False ,
336+ def _calculate_open_period_time_range (
337+ params : CalculateOpenPeriodTimeRangeParams ,
317338) -> tuple [datetime , datetime ]:
318- snuba_query = _unpack_snuba_query (incident .alert_rule )
319- time_window = snuba_query .time_window if incident .alert_rule is not None else 60
339+ time_window = params .snuba_query .time_window
320340 time_window_delta = timedelta (seconds = time_window )
321- start = (incident .date_started - time_window_delta ) if start_arg is None else start_arg
322- end = (incident .current_end_date + time_window_delta ) if end_arg is None else end_arg
323- if windowed_stats :
324- now = django_timezone .now ()
325- end = start + timedelta (seconds = time_window * (WINDOWED_STATS_DATA_POINTS / 2 ))
326- start = start - timedelta (seconds = time_window * (WINDOWED_STATS_DATA_POINTS / 2 ))
327- if end > now :
328- end = now
329-
330- # If the incident ended already, 'now' could be greater than we'd like
331- # which would result in showing too many data points after an incident ended.
332- # This depends on when the task to process snapshots runs.
333- # To resolve that, we ensure that the end is never greater than the date
334- # an incident ended + the smaller of time_window*10 or 10 days.
335- latest_end_date = incident .current_end_date + min (
336- timedelta (seconds = time_window * 10 ), timedelta (days = 10 )
337- )
338- end = min (end , latest_end_date )
339-
340- start = end - timedelta (seconds = time_window * WINDOWED_STATS_DATA_POINTS )
341+ start = (
342+ (params .date_started - time_window_delta ) if params .start_arg is None else params .start_arg
343+ )
344+ end = (
345+ (params .current_end_date + time_window_delta ) if params .end_arg is None else params .end_arg
346+ )
341347
342- retention = quotas .backend .get_event_retention (organization = incident .organization ) or 90
348+ retention = quotas .backend .get_event_retention (organization = params .organization ) or 90
343349 start = max (
344350 start .replace (tzinfo = timezone .utc ),
345351 datetime .now (timezone .utc ) - timedelta (days = retention ),
@@ -353,7 +359,6 @@ def get_incident_aggregates(
353359 incident : Incident ,
354360 start : datetime | None = None ,
355361 end : datetime | None = None ,
356- windowed_stats : bool = False ,
357362) -> dict [str , float | int ]:
358363 """
359364 Calculates aggregate stats across the life of an incident, or the provided range.
@@ -363,13 +368,20 @@ def get_incident_aggregates(
363368 snuba_query ,
364369 incident .organization_id ,
365370 )
366- if entity_subscription .dataset == Dataset .EventsAnalyticsPlatform :
367- start , end = _calculate_incident_time_range (
368- incident , start , end , windowed_stats = windowed_stats
369- )
371+ project_ids = list (
372+ IncidentProject .objects .filter (incident = incident ).values_list ("project_id" , flat = True )
373+ )
370374
371- project_ids = list (
372- IncidentProject .objects .filter (incident = incident ).values_list ("project_id" , flat = True )
375+ if entity_subscription .dataset == Dataset .EventsAnalyticsPlatform :
376+ start , end = _calculate_open_period_time_range (
377+ CalculateOpenPeriodTimeRangeParams (
378+ snuba_query = snuba_query ,
379+ date_started = incident .date_started ,
380+ current_end_date = incident .current_end_date ,
381+ organization = incident .organization ,
382+ start_arg = start ,
383+ end_arg = end ,
384+ )
373385 )
374386
375387 params = SnubaParams (
@@ -404,8 +416,17 @@ def get_incident_aggregates(
404416 )
405417 raise
406418 else :
407- query_builder = _build_incident_query_builder (
408- incident , entity_subscription , start , end , windowed_stats
419+ query_builder = _build_metric_query_builder (
420+ BuildMetricQueryBuilderParams (
421+ snuba_query = snuba_query ,
422+ organization = incident .organization ,
423+ project_ids = project_ids ,
424+ entity_subscription = entity_subscription ,
425+ date_started = incident .date_started ,
426+ current_end_date = incident .current_end_date ,
427+ start_arg = start ,
428+ end_arg = end ,
429+ )
409430 )
410431 try :
411432 results = query_builder .run_query (referrer = "incidents.get_incident_aggregates" )
0 commit comments