From 2d58cf2da4ee9f8e3e85b112c696303b4cb6f993 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Tue, 20 May 2025 11:58:16 +0200 Subject: [PATCH] feat(chalice): filter sessions by incidents --- api/chalicelib/core/sessions/sessions_ch.py | 63 ++++++++++++++++++- .../core/sessions/sessions_legacy_mobil.py | 2 +- api/chalicelib/core/sessions/sessions_pg.py | 2 +- api/chalicelib/utils/exp_ch_helper.py | 6 +- api/schemas/schemas.py | 4 +- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/api/chalicelib/core/sessions/sessions_ch.py b/api/chalicelib/core/sessions/sessions_ch.py index 3801609dc..7851ed1c8 100644 --- a/api/chalicelib/core/sessions/sessions_ch.py +++ b/api/chalicelib/core/sessions/sessions_ch.py @@ -379,6 +379,34 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu events_conditions_where = ["main.project_id = %(projectId)s", "main.created_at >= toDateTime(%(startDate)s/1000)", "main.created_at <= toDateTime(%(endDate)s/1000)"] + any_incident = False + for i, e in enumerate(data.events): + if e.type == schemas.EventType.INCIDENT and e.operator == schemas.SearchEventOperator.IS_ANY: + any_incident = True + data.events.pop(i) + # don't stop here because we could have multiple filters looking for any incident + + if any_incident: + any_incident = False + for f in data.filters: + if f.type == schemas.FilterType.ISSUE: + any_incident = True + if f.value.index(schemas.IssueType.INCIDENT) < 0: + f.value.append(schemas.IssueType.INCIDENT) + if f.operator == schemas.SearchEventOperator.IS_ANY: + f.operator = schemas.SearchEventOperator.IS + break + + if not any_incident: + data.filters.append(schemas.SessionSearchFilterSchema(**{ + "type": "issue", + "isEvent": False, + "value": [ + "incident" + ], + "operator": "is" + })) + if len(data.filters) > 0: meta_keys = None # to reduce include a sub-query of sessions inside events query, in order to reduce the selected data @@ -522,7 +550,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu ss_constraints.append( sh.multi_conditions(f"ms.base_referrer {op} toString(%({f_k})s)", f.value, is_not=is_not, value_key=f_k)) - elif filter_type == schemas.EventType.METADATA: + elif filter_type == schemas.FilterType.METADATA: # get metadata list only if you need it if meta_keys is None: meta_keys = metadata.get(project_id=project_id) @@ -1257,6 +1285,39 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu _column = "label" event_where.append(f"main.`$event_name`=%({e_k})s AND main.session_id>0") events_conditions.append({"type": event_where[-1], "condition": ""}) + elif event_type == schemas.EventType.INCIDENT: + event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " + _column = "label" + event_where.append( + f"main.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") + events_conditions.append({"type": event_where[-1]}) + + if is_not: + # event_where.append(json_condition( + # "sub", "$properties", _column, op, event.value, e_k + # )) + event_where.append( + sh.multi_conditions( + get_sub_condition(col_name=f"sub.`$properties`.{_column}", + val_name=e_k, operator=event.operator), + event.value, value_key=e_k) + ) + events_conditions_not.append( + { + "type": f"sub.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'" + } + ) + events_conditions_not[-1]["condition"] = event_where[-1] + else: + + event_where.append( + sh.multi_conditions( + get_sub_condition(col_name=f"main.`$properties`.{_column}", + val_name=e_k, operator=event.operator), + event.value, value_key=e_k) + ) + events_conditions[-1]["condition"] = event_where[-1] + else: continue diff --git a/api/chalicelib/core/sessions/sessions_legacy_mobil.py b/api/chalicelib/core/sessions/sessions_legacy_mobil.py index e9b0cffe1..885d08b5f 100644 --- a/api/chalicelib/core/sessions/sessions_legacy_mobil.py +++ b/api/chalicelib/core/sessions/sessions_legacy_mobil.py @@ -411,7 +411,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu ss_constraints.append( _multiple_conditions(f"ms.base_referrer {op} toString(%({f_k})s)", f.value, is_not=is_not, value_key=f_k)) - elif filter_type == schemas.EventType.METADATA: + elif filter_type == schemas.FilterType.METADATA: # get metadata list only if you need it if meta_keys is None: meta_keys = metadata.get(project_id=project_id) diff --git a/api/chalicelib/core/sessions/sessions_pg.py b/api/chalicelib/core/sessions/sessions_pg.py index 2c404d82e..fe42f4ebd 100644 --- a/api/chalicelib/core/sessions/sessions_pg.py +++ b/api/chalicelib/core/sessions/sessions_pg.py @@ -440,7 +440,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, extra_constraints.append( sh.multi_conditions(f"s.base_referrer {op} %({f_k})s", f.value, is_not=is_not, value_key=f_k)) - elif filter_type == schemas.EventType.METADATA: + elif filter_type == schemas.FilterType.METADATA: # get metadata list only if you need it if meta_keys is None: meta_keys = metadata.get(project_id=project_id) diff --git a/api/chalicelib/utils/exp_ch_helper.py b/api/chalicelib/utils/exp_ch_helper.py index aaf41afb2..a0d02a524 100644 --- a/api/chalicelib/utils/exp_ch_helper.py +++ b/api/chalicelib/utils/exp_ch_helper.py @@ -56,7 +56,8 @@ def get_event_type(event_type: Union[schemas.EventType, schemas.PerformanceEvent schemas.EventType.ERROR: "ERROR", schemas.PerformanceEventType.LOCATION_AVG_CPU_LOAD: 'PERFORMANCE', schemas.PerformanceEventType.LOCATION_AVG_MEMORY_USAGE: 'PERFORMANCE', - schemas.FetchFilterType.FETCH_URL: 'REQUEST' + schemas.FetchFilterType.FETCH_URL: 'REQUEST', + schemas.EventType.INCIDENT: "INCIDENT", } defs_mobile = { schemas.EventType.CLICK_MOBILE: "TAP", @@ -65,7 +66,8 @@ def get_event_type(event_type: Union[schemas.EventType, schemas.PerformanceEvent schemas.EventType.REQUEST_MOBILE: "REQUEST", schemas.EventType.ERROR_MOBILE: "CRASH", schemas.EventType.VIEW_MOBILE: "VIEW", - schemas.EventType.SWIPE_MOBILE: "SWIPE" + schemas.EventType.SWIPE_MOBILE: "SWIPE", + schemas.EventType.INCIDENT: "INCIDENT" } if platform != "web" and event_type in defs_mobile: return defs_mobile.get(event_type) diff --git a/api/schemas/schemas.py b/api/schemas/schemas.py index 7ab8f5ad4..6c38868a4 100644 --- a/api/schemas/schemas.py +++ b/api/schemas/schemas.py @@ -507,8 +507,8 @@ class IssueType(str, Enum): CUSTOM = 'custom' JS_EXCEPTION = 'js_exception' MOUSE_THRASHING = 'mouse_thrashing' - # IOS - TAP_RAGE = 'tap_rage' + TAP_RAGE = 'tap_rage' # IOS + INCIDENT = 'incident' class MetricFormatType(str, Enum):