From f8c927512756a060e8bb697eb82fd4ca8d1452a3 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Fri, 16 May 2025 14:19:11 +0200 Subject: [PATCH] refactor(chalice): refactored events --- .../core/autocomplete/autocomplete.py | 56 ++--- .../core/autocomplete/autocomplete_ch.py | 18 +- api/chalicelib/core/events/__init__.py | 11 + .../core/{ => events}/events_mobile.py | 4 +- api/chalicelib/core/events/events_pg.py | 201 ++++++++++++++++++ .../core/metrics/heatmaps/heatmaps_ch.py | 2 +- .../modules/significance/significance.py | 107 +++++----- .../modules/significance/significance_ch.py | 36 ++-- api/chalicelib/core/sessions/sessions_ch.py | 63 +++--- .../core/sessions/sessions_legacy_mobil.py | 84 ++++---- api/chalicelib/core/sessions/sessions_pg.py | 155 +++++++------- .../core/sessions/sessions_replay.py | 4 +- api/env.default | 3 +- api/env.dev | 3 +- ee/api/.gitignore | 3 +- ee/api/clean-dev.sh | 3 +- 16 files changed, 481 insertions(+), 272 deletions(-) create mode 100644 api/chalicelib/core/events/__init__.py rename api/chalicelib/core/{ => events}/events_mobile.py (95%) create mode 100644 api/chalicelib/core/events/events_pg.py diff --git a/api/chalicelib/core/autocomplete/autocomplete.py b/api/chalicelib/core/autocomplete/autocomplete.py index 648f0e652..8b5222769 100644 --- a/api/chalicelib/core/autocomplete/autocomplete.py +++ b/api/chalicelib/core/autocomplete/autocomplete.py @@ -1,9 +1,9 @@ import logging + import schemas -from chalicelib.core import countries, events, metadata +from chalicelib.core import countries, metadata from chalicelib.utils import helper from chalicelib.utils import pg_client -from chalicelib.utils.event_filter_definition import Event logger = logging.getLogger(__name__) TABLE = "public.autocomplete" @@ -112,10 +112,10 @@ def __generic_query(typename, value_length=None): LIMIT 10;""" -def __generic_autocomplete(event: Event): +def __generic_autocomplete(event: str): def f(project_id, value, key=None, source=None): with pg_client.PostgresClient() as cur: - query = __generic_query(event.ui_type, value_length=len(value)) + query = __generic_query(event, value_length=len(value)) params = {"project_id": project_id, "value": helper.string_to_sql_like(value), "svalue": helper.string_to_sql_like("^" + value)} cur.execute(cur.mogrify(query, params)) @@ -148,8 +148,8 @@ def __errors_query(source=None, value_length=None): return f"""((SELECT DISTINCT ON(lg.message) lg.message AS value, source, - '{events.EventType.ERROR.ui_type}' AS type - FROM {events.EventType.ERROR.table} INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR}' AS type + FROM events.errors INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.message ILIKE %(svalue)s @@ -160,8 +160,8 @@ def __errors_query(source=None, value_length=None): (SELECT DISTINCT ON(lg.name) lg.name AS value, source, - '{events.EventType.ERROR.ui_type}' AS type - FROM {events.EventType.ERROR.table} INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR}' AS type + FROM events.errors INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.name ILIKE %(svalue)s @@ -172,8 +172,8 @@ def __errors_query(source=None, value_length=None): (SELECT DISTINCT ON(lg.message) lg.message AS value, source, - '{events.EventType.ERROR.ui_type}' AS type - FROM {events.EventType.ERROR.table} INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR}' AS type + FROM events.errors INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.message ILIKE %(value)s @@ -184,8 +184,8 @@ def __errors_query(source=None, value_length=None): (SELECT DISTINCT ON(lg.name) lg.name AS value, source, - '{events.EventType.ERROR.ui_type}' AS type - FROM {events.EventType.ERROR.table} INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR}' AS type + FROM events.errors INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.name ILIKE %(value)s @@ -195,8 +195,8 @@ def __errors_query(source=None, value_length=None): return f"""((SELECT DISTINCT ON(lg.message) lg.message AS value, source, - '{events.EventType.ERROR.ui_type}' AS type - FROM {events.EventType.ERROR.table} INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR}' AS type + FROM events.errors INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.message ILIKE %(svalue)s @@ -207,8 +207,8 @@ def __errors_query(source=None, value_length=None): (SELECT DISTINCT ON(lg.name) lg.name AS value, source, - '{events.EventType.ERROR.ui_type}' AS type - FROM {events.EventType.ERROR.table} INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR}' AS type + FROM events.errors INNER JOIN public.errors AS lg USING (error_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.name ILIKE %(svalue)s @@ -233,8 +233,8 @@ def __search_errors_mobile(project_id, value, key=None, source=None): if len(value) > 2: query = f"""(SELECT DISTINCT ON(lg.reason) lg.reason AS value, - '{events.EventType.CRASH_MOBILE.ui_type}' AS type - FROM {events.EventType.CRASH_MOBILE.table} INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR_MOBILE}' AS type + FROM events_common.crashes INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.project_id = %(project_id)s @@ -243,8 +243,8 @@ def __search_errors_mobile(project_id, value, key=None, source=None): UNION ALL (SELECT DISTINCT ON(lg.name) lg.name AS value, - '{events.EventType.CRASH_MOBILE.ui_type}' AS type - FROM {events.EventType.CRASH_MOBILE.table} INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR_MOBILE}' AS type + FROM events_common.crashes INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.project_id = %(project_id)s @@ -253,8 +253,8 @@ def __search_errors_mobile(project_id, value, key=None, source=None): UNION ALL (SELECT DISTINCT ON(lg.reason) lg.reason AS value, - '{events.EventType.CRASH_MOBILE.ui_type}' AS type - FROM {events.EventType.CRASH_MOBILE.table} INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR_MOBILE}' AS type + FROM events_common.crashes INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.project_id = %(project_id)s @@ -263,8 +263,8 @@ def __search_errors_mobile(project_id, value, key=None, source=None): UNION ALL (SELECT DISTINCT ON(lg.name) lg.name AS value, - '{events.EventType.CRASH_MOBILE.ui_type}' AS type - FROM {events.EventType.CRASH_MOBILE.table} INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR_MOBILE}' AS type + FROM events_common.crashes INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.project_id = %(project_id)s @@ -273,8 +273,8 @@ def __search_errors_mobile(project_id, value, key=None, source=None): else: query = f"""(SELECT DISTINCT ON(lg.reason) lg.reason AS value, - '{events.EventType.CRASH_MOBILE.ui_type}' AS type - FROM {events.EventType.CRASH_MOBILE.table} INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR_MOBILE}' AS type + FROM events_common.crashes INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.project_id = %(project_id)s @@ -283,8 +283,8 @@ def __search_errors_mobile(project_id, value, key=None, source=None): UNION ALL (SELECT DISTINCT ON(lg.name) lg.name AS value, - '{events.EventType.CRASH_MOBILE.ui_type}' AS type - FROM {events.EventType.CRASH_MOBILE.table} INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) + '{schemas.EventType.ERROR_MOBILE}' AS type + FROM events_common.crashes INNER JOIN public.crashes_ios AS lg USING (crash_ios_id) LEFT JOIN public.sessions AS s USING(session_id) WHERE s.project_id = %(project_id)s AND lg.project_id = %(project_id)s diff --git a/api/chalicelib/core/autocomplete/autocomplete_ch.py b/api/chalicelib/core/autocomplete/autocomplete_ch.py index cbabf3ff5..daba725ce 100644 --- a/api/chalicelib/core/autocomplete/autocomplete_ch.py +++ b/api/chalicelib/core/autocomplete/autocomplete_ch.py @@ -1,9 +1,9 @@ import logging + import schemas -from chalicelib.core import countries, events, metadata +from chalicelib.core import countries, metadata from chalicelib.utils import ch_client from chalicelib.utils import helper, exp_ch_helper -from chalicelib.utils.event_filter_definition import Event logger = logging.getLogger(__name__) TABLE = "experimental.autocomplete" @@ -113,7 +113,7 @@ def __generic_query(typename, value_length=None): LIMIT 10;""" -def __generic_autocomplete(event: Event): +def __generic_autocomplete(event: str): def f(project_id, value, key=None, source=None): with ch_client.ClickHouseClient() as cur: query = __generic_query(event.ui_type, value_length=len(value)) @@ -149,7 +149,7 @@ def __pg_errors_query(source=None, value_length=None): return f"""((SELECT DISTINCT ON(message) message AS value, source, - '{events.EventType.ERROR.ui_type}' AS type + '{schemas.EventType.ERROR}' AS type FROM {MAIN_TABLE} WHERE project_id = %(project_id)s @@ -161,7 +161,7 @@ def __pg_errors_query(source=None, value_length=None): (SELECT DISTINCT ON(name) name AS value, source, - '{events.EventType.ERROR.ui_type}' AS type + '{schemas.EventType.ERROR}' AS type FROM {MAIN_TABLE} WHERE project_id = %(project_id)s @@ -172,7 +172,7 @@ def __pg_errors_query(source=None, value_length=None): (SELECT DISTINCT ON(message) message AS value, source, - '{events.EventType.ERROR.ui_type}' AS type + '{schemas.EventType.ERROR}' AS type FROM {MAIN_TABLE} WHERE project_id = %(project_id)s @@ -183,7 +183,7 @@ def __pg_errors_query(source=None, value_length=None): (SELECT DISTINCT ON(name) name AS value, source, - '{events.EventType.ERROR.ui_type}' AS type + '{schemas.EventType.ERROR}' AS type FROM {MAIN_TABLE} WHERE project_id = %(project_id)s @@ -193,7 +193,7 @@ def __pg_errors_query(source=None, value_length=None): return f"""((SELECT DISTINCT ON(message) message AS value, source, - '{events.EventType.ERROR.ui_type}' AS type + '{schemas.EventType.ERROR}' AS type FROM {MAIN_TABLE} WHERE project_id = %(project_id)s @@ -204,7 +204,7 @@ def __pg_errors_query(source=None, value_length=None): (SELECT DISTINCT ON(name) name AS value, source, - '{events.EventType.ERROR.ui_type}' AS type + '{schemas.EventType.ERROR}' AS type FROM {MAIN_TABLE} WHERE project_id = %(project_id)s diff --git a/api/chalicelib/core/events/__init__.py b/api/chalicelib/core/events/__init__.py new file mode 100644 index 000000000..d4df51f72 --- /dev/null +++ b/api/chalicelib/core/events/__init__.py @@ -0,0 +1,11 @@ +import logging + +from decouple import config + +logger = logging.getLogger(__name__) + +if config("EXP_EVENTS_REPLAY", cast=bool, default=False): + logger.info(">>> Using experimental events replay") + from . import events_ch as events +else: + from . import events_pg as events diff --git a/api/chalicelib/core/events_mobile.py b/api/chalicelib/core/events/events_mobile.py similarity index 95% rename from api/chalicelib/core/events_mobile.py rename to api/chalicelib/core/events/events_mobile.py index 166a7b633..346ab7832 100644 --- a/api/chalicelib/core/events_mobile.py +++ b/api/chalicelib/core/events/events_mobile.py @@ -1,5 +1,5 @@ from chalicelib.utils import pg_client, helper -from chalicelib.core import events +from . import events def get_customs_by_session_id(session_id, project_id): @@ -58,7 +58,7 @@ def get_crashes_by_session_id(session_id): with pg_client.PostgresClient() as cur: cur.execute(cur.mogrify(f""" SELECT cr.*,uc.*, cr.timestamp - s.start_ts AS time - FROM {events.EventType.CRASH_MOBILE.table} AS cr + FROM events_common.crashes AS cr INNER JOIN public.crashes_ios AS uc USING (crash_ios_id) INNER JOIN public.sessions AS s USING (session_id) WHERE diff --git a/api/chalicelib/core/events/events_pg.py b/api/chalicelib/core/events/events_pg.py new file mode 100644 index 000000000..62c599b6e --- /dev/null +++ b/api/chalicelib/core/events/events_pg.py @@ -0,0 +1,201 @@ +from functools import cache +from typing import Optional + +import schemas +from chalicelib.core import issues +from chalicelib.core.autocomplete import autocomplete +from chalicelib.core.sessions import sessions_metas +from chalicelib.utils import pg_client, helper +from chalicelib.utils.TimeUTC import TimeUTC +from chalicelib.utils.event_filter_definition import SupportedFilter + + +def get_customs_by_session_id(session_id, project_id): + with pg_client.PostgresClient() as cur: + cur.execute(cur.mogrify(""" \ + SELECT c.*, + 'CUSTOM' AS type + FROM events_common.customs AS c + WHERE c.session_id = %(session_id)s + ORDER BY c.timestamp;""", + {"project_id": project_id, "session_id": session_id}) + ) + rows = cur.fetchall() + return helper.dict_to_camel_case(rows) + + +def __merge_cells(rows, start, count, replacement): + rows[start] = replacement + rows = rows[:start + 1] + rows[start + count:] + return rows + + +def __get_grouped_clickrage(rows, session_id, project_id): + click_rage_issues = issues.get_by_session_id(session_id=session_id, issue_type="click_rage", project_id=project_id) + if len(click_rage_issues) == 0: + return rows + + for c in click_rage_issues: + merge_count = c.get("payload") + if merge_count is not None: + merge_count = merge_count.get("Count", 3) + else: + merge_count = 3 + for i in range(len(rows)): + if rows[i]["timestamp"] == c["timestamp"]: + rows = __merge_cells(rows=rows, + start=i, + count=merge_count, + replacement={**rows[i], "type": "CLICKRAGE", "count": merge_count}) + break + return rows + + +def get_by_session_id(session_id, project_id, group_clickrage=False, event_type: Optional[schemas.EventType] = None): + with pg_client.PostgresClient() as cur: + rows = [] + if event_type is None or event_type == schemas.EventType.CLICK: + cur.execute(cur.mogrify(""" \ + SELECT c.*, + 'CLICK' AS type + FROM events.clicks AS c + WHERE c.session_id = %(session_id)s + ORDER BY c.timestamp;""", + {"project_id": project_id, "session_id": session_id}) + ) + rows += cur.fetchall() + if group_clickrage: + rows = __get_grouped_clickrage(rows=rows, session_id=session_id, project_id=project_id) + if event_type is None or event_type == schemas.EventType.INPUT: + cur.execute(cur.mogrify(""" + SELECT i.*, + 'INPUT' AS type + FROM events.inputs AS i + WHERE i.session_id = %(session_id)s + ORDER BY i.timestamp;""", + {"project_id": project_id, "session_id": session_id}) + ) + rows += cur.fetchall() + if event_type is None or event_type == schemas.EventType.LOCATION: + cur.execute(cur.mogrify(""" \ + SELECT l.*, + l.path AS value, + l.path AS url, + 'LOCATION' AS type + FROM events.pages AS l + WHERE + l.session_id = %(session_id)s + ORDER BY l.timestamp;""", {"project_id": project_id, "session_id": session_id})) + rows += cur.fetchall() + rows = helper.list_to_camel_case(rows) + rows = sorted(rows, key=lambda k: (k["timestamp"], k["messageId"])) + return rows + + +def _search_tags(project_id, value, key=None, source=None): + with pg_client.PostgresClient() as cur: + query = f""" + SELECT public.tags.name + 'TAG' AS type + FROM public.tags + WHERE public.tags.project_id = %(project_id)s + ORDER BY SIMILARITY(public.tags.name, %(value)s) DESC + LIMIT 10 + """ + query = cur.mogrify(query, {'project_id': project_id, 'value': value}) + cur.execute(query) + results = helper.list_to_camel_case(cur.fetchall()) + return results + + +@cache +def supported_types(): + return { + schemas.EventType.CLICK: SupportedFilter(get=autocomplete.__generic_autocomplete(schemas.EventType.CLICK), + query=autocomplete.__generic_query(typename=schemas.EventType.CLICK)), + schemas.EventType.INPUT: SupportedFilter(get=autocomplete.__generic_autocomplete(schemas.EventType.INPUT), + query=autocomplete.__generic_query(typename=schemas.EventType.INPUT)), + schemas.EventType.LOCATION: SupportedFilter(get=autocomplete.__generic_autocomplete(schemas.EventType.LOCATION), + query=autocomplete.__generic_query( + typename=schemas.EventType.LOCATION)), + schemas.EventType.CUSTOM: SupportedFilter(get=autocomplete.__generic_autocomplete(schemas.EventType.CUSTOM), + query=autocomplete.__generic_query( + typename=schemas.EventType.CUSTOM)), + schemas.EventType.REQUEST: SupportedFilter(get=autocomplete.__generic_autocomplete(schemas.EventType.REQUEST), + query=autocomplete.__generic_query( + typename=schemas.EventType.REQUEST)), + schemas.EventType.GRAPHQL: SupportedFilter(get=autocomplete.__generic_autocomplete(schemas.EventType.GRAPHQL), + query=autocomplete.__generic_query( + typename=schemas.EventType.GRAPHQL)), + schemas.EventType.STATE_ACTION: SupportedFilter( + get=autocomplete.__generic_autocomplete(schemas.EventType.STATEACTION), + query=autocomplete.__generic_query( + typename=schemas.EventType.STATE_ACTION)), + schemas.EventType.TAG: SupportedFilter(get=_search_tags, query=None), + schemas.EventType.ERROR: SupportedFilter(get=autocomplete.__search_errors, + query=None), + schemas.FilterType.METADATA: SupportedFilter(get=autocomplete.__search_metadata, + query=None), + # MOBILE + schemas.EventType.CLICK_MOBILE: SupportedFilter( + get=autocomplete.__generic_autocomplete(schemas.EventType.CLICK_MOBILE), + query=autocomplete.__generic_query( + typename=schemas.EventType.CLICK_MOBILE)), + schemas.EventType.SWIPE_MOBILE: SupportedFilter( + get=autocomplete.__generic_autocomplete(schemas.EventType.SWIPE_MOBILE), + query=autocomplete.__generic_query( + typename=schemas.EventType.SWIPE_MOBILE)), + schemas.EventType.INPUT_MOBILE: SupportedFilter( + get=autocomplete.__generic_autocomplete(schemas.EventType.INPUT_MOBILE), + query=autocomplete.__generic_query( + typename=schemas.EventType.INPUT_MOBILE)), + schemas.EventType.VIEW_MOBILE: SupportedFilter( + get=autocomplete.__generic_autocomplete(schemas.EventType.VIEW_MOBILE), + query=autocomplete.__generic_query( + typename=schemas.EventType.VIEW_MOBILE)), + schemas.EventType.CUSTOM_MOBILE: SupportedFilter( + get=autocomplete.__generic_autocomplete(schemas.EventType.CUSTOM_MOBILE), + query=autocomplete.__generic_query( + typename=schemas.EventType.CUSTOM_MOBILE)), + schemas.EventType.REQUEST_MOBILE: SupportedFilter( + get=autocomplete.__generic_autocomplete(schemas.EventType.REQUEST_MOBILE), + query=autocomplete.__generic_query( + typename=schemas.EventType.REQUEST_MOBILE)), + schemas.EventType.ERROR_MOBILE: SupportedFilter(get=autocomplete.__search_errors_mobile, + query=None), + } + + +def get_errors_by_session_id(session_id, project_id): + with pg_client.PostgresClient() as cur: + cur.execute(cur.mogrify(f"""\ + SELECT er.*,ur.*, er.timestamp - s.start_ts AS time + FROM events.errors AS er INNER JOIN public.errors AS ur USING (error_id) INNER JOIN public.sessions AS s USING (session_id) + WHERE er.session_id = %(session_id)s AND s.project_id=%(project_id)s + ORDER BY timestamp;""", {"session_id": session_id, "project_id": project_id})) + errors = cur.fetchall() + for e in errors: + e["stacktrace_parsed_at"] = TimeUTC.datetime_to_timestamp(e["stacktrace_parsed_at"]) + return helper.list_to_camel_case(errors) + + +def search(text, event_type, project_id, source, key): + if not event_type: + return {"data": autocomplete.__get_autocomplete_table(text, project_id)} + + if event_type in supported_types().keys(): + rows = supported_types()[event_type].get(project_id=project_id, value=text, key=key, source=source) + elif event_type + "_MOBILE" in supported_types().keys(): + rows = supported_types()[event_type + "_MOBILE"].get(project_id=project_id, value=text, key=key, source=source) + elif event_type in sessions_metas.supported_types().keys(): + return sessions_metas.search(text, event_type, project_id) + elif event_type.endswith("_IOS") \ + and event_type[:-len("_IOS")] in sessions_metas.supported_types().keys(): + return sessions_metas.search(text, event_type, project_id) + elif event_type.endswith("_MOBILE") \ + and event_type[:-len("_MOBILE")] in sessions_metas.supported_types().keys(): + return sessions_metas.search(text, event_type, project_id) + else: + return {"errors": ["unsupported event"]} + + return {"data": rows} diff --git a/api/chalicelib/core/metrics/heatmaps/heatmaps_ch.py b/api/chalicelib/core/metrics/heatmaps/heatmaps_ch.py index 519f6ddcb..e7399f230 100644 --- a/api/chalicelib/core/metrics/heatmaps/heatmaps_ch.py +++ b/api/chalicelib/core/metrics/heatmaps/heatmaps_ch.py @@ -3,7 +3,7 @@ import logging from decouple import config import schemas -from chalicelib.core import events +from chalicelib.core.events import events from chalicelib.core.metrics.modules import sessions, sessions_mobs from chalicelib.utils import sql_helper as sh diff --git a/api/chalicelib/core/metrics/modules/significance/significance.py b/api/chalicelib/core/metrics/modules/significance/significance.py index 38815c806..8352feb94 100644 --- a/api/chalicelib/core/metrics/modules/significance/significance.py +++ b/api/chalicelib/core/metrics/modules/significance/significance.py @@ -7,7 +7,8 @@ from typing import List from psycopg2.extras import RealDictRow import schemas -from chalicelib.core import events, metadata +from chalicelib.core import metadata +from chalicelib.core.events import events from chalicelib.utils import pg_client, helper from chalicelib.utils import sql_helper as sh @@ -76,10 +77,10 @@ def get_stages_and_events(filter_d: schemas.CardSeriesFilterSchema, project_id) values["maxDuration"] = f.value[1] elif filter_type == schemas.FilterType.REFERRER: # events_query_part = events_query_part + f"INNER JOIN events.pages AS p USING(session_id)" - filter_extra_from = [f"INNER JOIN {events.EventType.LOCATION.table} AS p USING(session_id)"] + filter_extra_from = [f"INNER JOIN {"events.pages"} AS p USING(session_id)"] first_stage_extra_constraints.append( sh.multi_conditions(f"p.base_referrer {op} %({f_k})s", f.value, is_not=is_not, value_key=f_k)) - elif filter_type == events.EventType.METADATA.ui_type: + elif filter_type == schemas.FilterType.METADATA: if meta_keys is None: meta_keys = metadata.get(project_id=project_id) meta_keys = {m["key"]: m["index"] for m in meta_keys} @@ -121,31 +122,31 @@ def get_stages_and_events(filter_d: schemas.CardSeriesFilterSchema, project_id) op = sh.get_sql_operator(s.operator) # event_type = s["type"].upper() event_type = s.type - if event_type == events.EventType.CLICK.ui_type: - next_table = events.EventType.CLICK.table - next_col_name = events.EventType.CLICK.column - elif event_type == events.EventType.INPUT.ui_type: - next_table = events.EventType.INPUT.table - next_col_name = events.EventType.INPUT.column - elif event_type == events.EventType.LOCATION.ui_type: - next_table = events.EventType.LOCATION.table - next_col_name = events.EventType.LOCATION.column - elif event_type == events.EventType.CUSTOM.ui_type: - next_table = events.EventType.CUSTOM.table - next_col_name = events.EventType.CUSTOM.column + if event_type == schemas.EventType.CLICK: + next_table = "events.clicks" + next_col_name = "label" + elif event_type == schemas.EventType.INPUT: + next_table = "events.inputs" + next_col_name = "label" + elif event_type == schemas.EventType.LOCATION: + next_table = "events.pages" + next_col_name = "path" + elif event_type == schemas.EventType.CUSTOM: + next_table = "events_common.customs" + next_col_name = "name" # IOS -------------- - elif event_type == events.EventType.CLICK_MOBILE.ui_type: - next_table = events.EventType.CLICK_MOBILE.table - next_col_name = events.EventType.CLICK_MOBILE.column - elif event_type == events.EventType.INPUT_MOBILE.ui_type: - next_table = events.EventType.INPUT_MOBILE.table - next_col_name = events.EventType.INPUT_MOBILE.column - elif event_type == events.EventType.VIEW_MOBILE.ui_type: - next_table = events.EventType.VIEW_MOBILE.table - next_col_name = events.EventType.VIEW_MOBILE.column - elif event_type == events.EventType.CUSTOM_MOBILE.ui_type: - next_table = events.EventType.CUSTOM_MOBILE.table - next_col_name = events.EventType.CUSTOM_MOBILE.column + elif event_type == schemas.EventType.CLICK_MOBILE: + next_table = "events_ios.taps" + next_col_name = "label" + elif event_type == schemas.EventType.INPUT_MOBILE: + next_table = "events_ios.inputs" + next_col_name = "label" + elif event_type == schemas.EventType.VIEW_MOBILE: + next_table = "events_ios.views" + next_col_name = "name" + elif event_type == schemas.EventType.CUSTOM_MOBILE: + next_table = "events_common.customs" + next_col_name = "name" else: logger.warning(f"=================UNDEFINED:{event_type}") continue @@ -297,10 +298,10 @@ def get_simple_funnel(filter_d: schemas.CardSeriesFilterSchema, project: schemas values["maxDuration"] = f.value[1] elif filter_type == schemas.FilterType.REFERRER: # events_query_part = events_query_part + f"INNER JOIN events.pages AS p USING(session_id)" - filter_extra_from = [f"INNER JOIN {events.EventType.LOCATION.table} AS p USING(session_id)"] + filter_extra_from = [f"INNER JOIN {"events.pages"} AS p USING(session_id)"] first_stage_extra_constraints.append( sh.multi_conditions(f"p.base_referrer {op} %({f_k})s", f.value, is_not=is_not, value_key=f_k)) - elif filter_type == events.EventType.METADATA.ui_type: + elif filter_type == schemas.FilterType.METADATA: if meta_keys is None: meta_keys = metadata.get(project_id=project.project_id) meta_keys = {m["key"]: m["index"] for m in meta_keys} @@ -342,31 +343,31 @@ def get_simple_funnel(filter_d: schemas.CardSeriesFilterSchema, project: schemas op = sh.get_sql_operator(s.operator) # event_type = s["type"].upper() event_type = s.type - if event_type == events.EventType.CLICK.ui_type: - next_table = events.EventType.CLICK.table - next_col_name = events.EventType.CLICK.column - elif event_type == events.EventType.INPUT.ui_type: - next_table = events.EventType.INPUT.table - next_col_name = events.EventType.INPUT.column - elif event_type == events.EventType.LOCATION.ui_type: - next_table = events.EventType.LOCATION.table - next_col_name = events.EventType.LOCATION.column - elif event_type == events.EventType.CUSTOM.ui_type: - next_table = events.EventType.CUSTOM.table - next_col_name = events.EventType.CUSTOM.column + if event_type == schemas.EventType.CLICK: + next_table = "events.clicks" + next_col_name = "label" + elif event_type == schemas.EventType.INPUT: + next_table = "events.inputs" + next_col_name = "label" + elif event_type == schemas.EventType.LOCATION: + next_table = "events.pages" + next_col_name = "path" + elif event_type == schemas.EventType.CUSTOM: + next_table = "events_common.customs" + next_col_name = "name" # IOS -------------- - elif event_type == events.EventType.CLICK_MOBILE.ui_type: - next_table = events.EventType.CLICK_MOBILE.table - next_col_name = events.EventType.CLICK_MOBILE.column - elif event_type == events.EventType.INPUT_MOBILE.ui_type: - next_table = events.EventType.INPUT_MOBILE.table - next_col_name = events.EventType.INPUT_MOBILE.column - elif event_type == events.EventType.VIEW_MOBILE.ui_type: - next_table = events.EventType.VIEW_MOBILE.table - next_col_name = events.EventType.VIEW_MOBILE.column - elif event_type == events.EventType.CUSTOM_MOBILE.ui_type: - next_table = events.EventType.CUSTOM_MOBILE.table - next_col_name = events.EventType.CUSTOM_MOBILE.column + elif event_type == schemas.EventType.CLICK_MOBILE: + next_table = "events_ios.taps" + next_col_name = "label" + elif event_type == schemas.EventType.INPUT_MOBILE: + next_table = "events_ios.inputs" + next_col_name = "label" + elif event_type == schemas.EventType.VIEW_MOBILE: + next_table = "events_ios.views" + next_col_name = "name" + elif event_type == schemas.EventType.CUSTOM_MOBILE: + next_table = "events_common.customs" + next_col_name = "name" else: logger.warning(f"=================UNDEFINED:{event_type}") continue diff --git a/api/chalicelib/core/metrics/modules/significance/significance_ch.py b/api/chalicelib/core/metrics/modules/significance/significance_ch.py index 0cceaf928..5d4e89182 100644 --- a/api/chalicelib/core/metrics/modules/significance/significance_ch.py +++ b/api/chalicelib/core/metrics/modules/significance/significance_ch.py @@ -8,7 +8,7 @@ from chalicelib.utils import ch_client from chalicelib.utils import exp_ch_helper from chalicelib.utils import helper from chalicelib.utils import sql_helper as sh -from chalicelib.core import events +from chalicelib.core.events import events logger = logging.getLogger(__name__) @@ -82,7 +82,7 @@ def get_simple_funnel(filter_d: schemas.CardSeriesFilterSchema, project: schemas elif filter_type == schemas.FilterType.REFERRER: 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 == events.EventType.METADATA.ui_type: + elif filter_type == schemas.FilterType.METADATA: if meta_keys is None: meta_keys = metadata.get(project_id=project.project_id) meta_keys = {m["key"]: m["index"] for m in meta_keys} @@ -125,29 +125,29 @@ def get_simple_funnel(filter_d: schemas.CardSeriesFilterSchema, project: schemas e_k = f"e_value{i}" event_type = s.type next_event_type = exp_ch_helper.get_event_type(event_type, platform=platform) - if event_type == events.EventType.CLICK.ui_type: + if event_type == schemas.EventType.CLICK: if platform == "web": - next_col_name = events.EventType.CLICK.column + next_col_name = "label" if not is_any: if schemas.ClickEventExtraOperator.has_value(s.operator): specific_condition = sh.multi_conditions(f"selector {op} %({e_k})s", s.value, value_key=e_k) else: - next_col_name = events.EventType.CLICK_MOBILE.column - elif event_type == events.EventType.INPUT.ui_type: - next_col_name = events.EventType.INPUT.column - elif event_type == events.EventType.LOCATION.ui_type: + next_col_name = "label" + elif event_type == schemas.EventType.INPUT: + next_col_name = "label" + elif event_type == schemas.EventType.LOCATION: next_col_name = 'url_path' - elif event_type == events.EventType.CUSTOM.ui_type: - next_col_name = events.EventType.CUSTOM.column + elif event_type == schemas.EventType.CUSTOM: + next_col_name = "name" # IOS -------------- - elif event_type == events.EventType.CLICK_MOBILE.ui_type: - next_col_name = events.EventType.CLICK_MOBILE.column - elif event_type == events.EventType.INPUT_MOBILE.ui_type: - next_col_name = events.EventType.INPUT_MOBILE.column - elif event_type == events.EventType.VIEW_MOBILE.ui_type: - next_col_name = events.EventType.VIEW_MOBILE.column - elif event_type == events.EventType.CUSTOM_MOBILE.ui_type: - next_col_name = events.EventType.CUSTOM_MOBILE.column + elif event_type == schemas.EventType.CLICK_MOBILE: + next_col_name = "label" + elif event_type == schemas.EventType.INPUT_MOBILE: + next_col_name = "label" + elif event_type == schemas.EventType.VIEW_MOBILE: + next_col_name = "name" + elif event_type == schemas.EventType.CUSTOM_MOBILE: + next_col_name = "name" else: logger.warning(f"=================UNDEFINED:{event_type}") continue diff --git a/api/chalicelib/core/sessions/sessions_ch.py b/api/chalicelib/core/sessions/sessions_ch.py index 8d1929c70..3801609dc 100644 --- a/api/chalicelib/core/sessions/sessions_ch.py +++ b/api/chalicelib/core/sessions/sessions_ch.py @@ -2,7 +2,8 @@ import logging from typing import List, Union import schemas -from chalicelib.core import events, metadata +from chalicelib.core import metadata +from chalicelib.core.events import events from . import performance_event, sessions_legacy from chalicelib.utils import pg_client, helper, metrics_helper, ch_client, exp_ch_helper from chalicelib.utils import sql_helper as sh @@ -521,7 +522,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 == events.EventType.METADATA.ui_type: + elif filter_type == schemas.EventType.METADATA: # get metadata list only if you need it if meta_keys is None: meta_keys = metadata.get(project_id=project_id) @@ -668,10 +669,10 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu **sh.multi_values(event.source, value_key=s_k), e_k: event.value[0] if len(event.value) > 0 else event.value} - if event_type == events.EventType.CLICK.ui_type: + if event_type == schemas.EventType.CLICK: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " if platform == "web": - _column = events.EventType.CLICK.column + _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]}) @@ -718,7 +719,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu ) events_conditions[-1]["condition"] = event_where[-1] else: - _column = events.EventType.CLICK_MOBILE.column + _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]}) @@ -737,10 +738,10 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu ) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.INPUT.ui_type: + elif event_type == schemas.EventType.INPUT: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " if platform == "web": - _column = events.EventType.INPUT.column + _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]}) @@ -765,7 +766,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu full_args = {**full_args, **sh.multi_values(event.source, value_key=f"custom{i}")} else: - _column = events.EventType.INPUT_MOBILE.column + _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]}) @@ -785,7 +786,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.LOCATION.ui_type: + elif event_type == schemas.EventType.LOCATION: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " if platform == "web": _column = 'url_path' @@ -807,7 +808,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu ) events_conditions[-1]["condition"] = event_where[-1] else: - _column = events.EventType.VIEW_MOBILE.column + _column = "name" event_where.append( f"main.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -824,9 +825,9 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(sh.multi_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.CUSTOM.ui_type: + elif event_type == schemas.EventType.CUSTOM: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " - _column = events.EventType.CUSTOM.column + _column = "name" event_where.append( f"main.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -844,7 +845,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu "main", "$properties", _column, op, event.value, e_k )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.REQUEST.ui_type: + elif event_type == schemas.EventType.REQUEST: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " _column = 'url_path' event_where.append( @@ -865,9 +866,9 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.STATEACTION.ui_type: + elif event_type == schemas.EventType.STATE_ACTION: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " - _column = events.EventType.STATEACTION.column + _column = "name" event_where.append( f"main.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -886,7 +887,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu )) events_conditions[-1]["condition"] = event_where[-1] # TODO: isNot for ERROR - elif event_type == events.EventType.ERROR.ui_type: + elif event_type == schemas.EventType.ERROR: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main" events_extra_join = f"SELECT * FROM {MAIN_EVENTS_TABLE} AS main1 WHERE main1.project_id=%(project_id)s" event_where.append( @@ -911,8 +912,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu events_conditions[-1]["condition"] = " AND ".join(events_conditions[-1]["condition"]) # ----- Mobile - elif event_type == events.EventType.CLICK_MOBILE.ui_type: - _column = events.EventType.CLICK_MOBILE.column + elif event_type == schemas.EventType.CLICK_MOBILE: + _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]}) @@ -930,8 +931,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu "main", "$properties", _column, op, event.value, e_k )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.INPUT_MOBILE.ui_type: - _column = events.EventType.INPUT_MOBILE.column + elif event_type == schemas.EventType.INPUT_MOBILE: + _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]}) @@ -949,8 +950,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu "main", "$properties", _column, op, event.value, e_k )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.VIEW_MOBILE.ui_type: - _column = events.EventType.VIEW_MOBILE.column + elif event_type == schemas.EventType.VIEW_MOBILE: + _column = "name" event_where.append( f"main.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -968,8 +969,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu "main", "$properties", _column, op, event.value, e_k )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.CUSTOM_MOBILE.ui_type: - _column = events.EventType.CUSTOM_MOBILE.column + elif event_type == schemas.EventType.CUSTOM_MOBILE: + _column = "name" event_where.append( f"main.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -988,7 +989,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.REQUEST_MOBILE.ui_type: + elif event_type == schemas.EventType.REQUEST_MOBILE: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " _column = 'url_path' event_where.append( @@ -1008,8 +1009,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu "main", "$properties", _column, op, event.value, e_k )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.CRASH_MOBILE.ui_type: - _column = events.EventType.CRASH_MOBILE.column + elif event_type == schemas.EventType.ERROR_MOBILE: + _column = "name" event_where.append( f"main.`$event_name`='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -1028,8 +1029,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu "main", "$properties", _column, op, event.value, e_k )) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.SWIPE_MOBILE.ui_type and platform != "web": - _column = events.EventType.SWIPE_MOBILE.column + elif event_type == schemas.EventType.SWIPE_MOBILE and platform != "web": + _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]}) @@ -1230,7 +1231,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu full_args = {**full_args, **sh.multi_values(f.value, value_key=e_k_f)} if f.type == schemas.GraphqlFilterType.GRAPHQL_NAME: event_where.append(json_condition( - "main", "$properties", events.EventType.GRAPHQL.column, op, f.value, e_k_f + "main", "$properties", "name", op, f.value, e_k_f )) events_conditions[-1]["condition"].append(event_where[-1]) elif f.type == schemas.GraphqlFilterType.GRAPHQL_METHOD: @@ -1253,7 +1254,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu events_conditions[-1]["condition"] = " AND ".join(events_conditions[-1]["condition"]) elif event_type == schemas.EventType.EVENT: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " - _column = events.EventType.CLICK.column + _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": ""}) diff --git a/api/chalicelib/core/sessions/sessions_legacy_mobil.py b/api/chalicelib/core/sessions/sessions_legacy_mobil.py index 69044812c..e9b0cffe1 100644 --- a/api/chalicelib/core/sessions/sessions_legacy_mobil.py +++ b/api/chalicelib/core/sessions/sessions_legacy_mobil.py @@ -2,7 +2,8 @@ import ast import logging import schemas -from chalicelib.core import events, metadata, projects +from chalicelib.core import metadata, projects +from chalicelib.core.events import events from chalicelib.core.sessions import performance_event, sessions_favorite, sessions_legacy from chalicelib.utils import pg_client, helper, ch_client, exp_ch_helper from chalicelib.utils import sql_helper as sh @@ -410,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 == events.EventType.METADATA.ui_type: + elif filter_type == schemas.EventType.METADATA: # get metadata list only if you need it if meta_keys is None: meta_keys = metadata.get(project_id=project_id) @@ -556,10 +557,10 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu **_multiple_values(event.value, value_key=e_k), **_multiple_values(event.source, value_key=s_k)} - if event_type == events.EventType.CLICK.ui_type: + if event_type == schemas.EventType.CLICK: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " if platform == "web": - _column = events.EventType.CLICK.column + _column = "label" event_where.append( f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -581,7 +582,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] else: - _column = events.EventType.CLICK_MOBILE.column + _column = "label" event_where.append( f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -598,10 +599,10 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.INPUT.ui_type: + elif event_type == schemas.EventType.INPUT: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " if platform == "web": - _column = events.EventType.INPUT.column + _column = "label" event_where.append( f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -622,7 +623,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu value_key=f"custom{i}")) full_args = {**full_args, **_multiple_values(event.source, value_key=f"custom{i}")} else: - _column = events.EventType.INPUT_MOBILE.column + _column = "label" event_where.append( f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -639,7 +640,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.LOCATION.ui_type: + elif event_type == schemas.EventType.LOCATION: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " if platform == "web": _column = 'url_path' @@ -659,7 +660,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] else: - _column = events.EventType.VIEW_MOBILE.column + _column = "name" event_where.append( f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) @@ -675,9 +676,9 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.CUSTOM.ui_type: + elif event_type == schemas.EventType.CUSTOM: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " - _column = events.EventType.CUSTOM.column + _column = "name" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -691,7 +692,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.REQUEST.ui_type: + elif event_type == schemas.EventType.REQUEST: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " _column = 'url_path' event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") @@ -708,9 +709,9 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.STATEACTION.ui_type: + elif event_type == schemas.EventType.STATE_ACTION: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " - _column = events.EventType.STATEACTION.column + _column = "name" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -725,7 +726,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] # TODO: isNot for ERROR - elif event_type == events.EventType.ERROR.ui_type: + elif event_type == schemas.EventType.ERROR: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main" events_extra_join = f"SELECT * FROM {MAIN_EVENTS_TABLE} AS main1 WHERE main1.project_id=%(project_id)s" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") @@ -746,8 +747,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu events_conditions[-1]["condition"] = " AND ".join(events_conditions[-1]["condition"]) # ----- Mobile - elif event_type == events.EventType.CLICK_MOBILE.ui_type: - _column = events.EventType.CLICK_MOBILE.column + elif event_type == schemas.EventType.CLICK_MOBILE: + _column = "label" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -761,8 +762,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.INPUT_MOBILE.ui_type: - _column = events.EventType.INPUT_MOBILE.column + elif event_type == schemas.EventType.INPUT_MOBILE: + _column = "label" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -776,8 +777,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.VIEW_MOBILE.ui_type: - _column = events.EventType.VIEW_MOBILE.column + elif event_type == schemas.EventType.VIEW_MOBILE: + _column = "name" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -791,8 +792,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.CUSTOM_MOBILE.ui_type: - _column = events.EventType.CUSTOM_MOBILE.column + elif event_type == schemas.EventType.CUSTOM_MOBILE: + _column = "name" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -806,7 +807,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.REQUEST_MOBILE.ui_type: + elif event_type == schemas.EventType.REQUEST_MOBILE: event_from = event_from % f"{MAIN_EVENTS_TABLE} AS main " _column = 'url_path' event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") @@ -822,8 +823,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.CRASH_MOBILE.ui_type: - _column = events.EventType.CRASH_MOBILE.column + elif event_type == schemas.EventType.ERROR_MOBILE: + _column = "name" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -837,8 +838,8 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu event_where.append(_multiple_conditions(f"main.{_column} {op} %({e_k})s", event.value, value_key=e_k)) events_conditions[-1]["condition"] = event_where[-1] - elif event_type == events.EventType.SWIPE_MOBILE.ui_type and platform != "web": - _column = events.EventType.SWIPE_MOBILE.column + elif event_type == schemas.EventType.SWIPE_MOBILE and platform != "web": + _column = "label" event_where.append(f"main.event_type='{exp_ch_helper.get_event_type(event_type, platform=platform)}'") events_conditions.append({"type": event_where[-1]}) if not is_any: @@ -992,7 +993,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu full_args = {**full_args, **_multiple_values(f.value, value_key=e_k_f)} if f.type == schemas.GraphqlFilterType.GRAPHQL_NAME: event_where.append( - _multiple_conditions(f"main.{events.EventType.GRAPHQL.column} {op} %({e_k_f})s", f.value, + _multiple_conditions(f"main.name {op} %({e_k_f})s", f.value, value_key=e_k_f)) events_conditions[-1]["condition"].append(event_where[-1]) elif f.type == schemas.GraphqlFilterType.GRAPHQL_METHOD: @@ -1221,7 +1222,7 @@ def search_query_parts_ch(data: schemas.SessionsSearchPayloadSchema, error_statu c.value = helper.values_for_operator(value=c.value, op=c.operator) full_args = {**full_args, **_multiple_values(c.value, value_key=e_k)} - if c.type == events.EventType.LOCATION.ui_type: + if c.type == schemas.EventType.LOCATION: _extra_or_condition.append( _multiple_conditions(f"extra_event.url_path {op} %({e_k})s", c.value, value_key=e_k)) @@ -1358,18 +1359,15 @@ def get_user_sessions(project_id, user_id, start_date, end_date): def get_session_user(project_id, user_id): with pg_client.PostgresClient() as cur: query = cur.mogrify( - """\ - SELECT - user_id, - count(*) as session_count, - max(start_ts) as last_seen, - min(start_ts) as first_seen - FROM - "public".sessions - WHERE - project_id = %(project_id)s - AND user_id = %(userId)s - AND duration is not null + """ \ + SELECT user_id, + count(*) as session_count, + max(start_ts) as last_seen, + min(start_ts) as first_seen + FROM "public".sessions + WHERE project_id = %(project_id)s + AND user_id = %(userId)s + AND duration is not null GROUP BY user_id; """, {"project_id": project_id, "userId": user_id} diff --git a/api/chalicelib/core/sessions/sessions_pg.py b/api/chalicelib/core/sessions/sessions_pg.py index 3032affcb..2c404d82e 100644 --- a/api/chalicelib/core/sessions/sessions_pg.py +++ b/api/chalicelib/core/sessions/sessions_pg.py @@ -2,7 +2,8 @@ import logging from typing import List, Union import schemas -from chalicelib.core import events, metadata +from chalicelib.core.events import events +from chalicelib.core import metadata from . import performance_event from chalicelib.utils import pg_client, helper, metrics_helper from chalicelib.utils import sql_helper as sh @@ -439,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 == events.EventType.METADATA.ui_type: + elif filter_type == schemas.EventType.METADATA: # get metadata list only if you need it if meta_keys is None: meta_keys = metadata.get(project_id=project_id) @@ -580,36 +581,36 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, **sh.multi_values(event.value, value_key=e_k), **sh.multi_values(event.source, value_key=s_k)} - if event_type == events.EventType.CLICK.ui_type: + if event_type == schemas.EventType.CLICK: if platform == "web": - event_from = event_from % f"{events.EventType.CLICK.table} AS main " + event_from = event_from % f"events.clicks AS main " if not is_any: if schemas.ClickEventExtraOperator.has_value(event.operator): event_where.append( sh.multi_conditions(f"main.selector {op} %({e_k})s", event.value, value_key=e_k)) else: event_where.append( - sh.multi_conditions(f"main.{events.EventType.CLICK.column} {op} %({e_k})s", event.value, + sh.multi_conditions(f"main.label {op} %({e_k})s", event.value, value_key=e_k)) else: - event_from = event_from % f"{events.EventType.CLICK_MOBILE.table} AS main " + event_from = event_from % f"events_ios.taps AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.CLICK_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.label {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.TAG.ui_type: - event_from = event_from % f"{events.EventType.TAG.table} AS main " + elif event_type == schemas.EventType.TAG: + event_from = event_from % f"events.tags AS main " if not is_any: event_where.append( sh.multi_conditions(f"main.tag_id = %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.INPUT.ui_type: + elif event_type == schemas.EventType.INPUT: if platform == "web": - event_from = event_from % f"{events.EventType.INPUT.table} AS main " + event_from = event_from % f"events.inputs AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.INPUT.column} {op} %({e_k})s", event.value, + sh.multi_conditions(f"main.label {op} %({e_k})s", event.value, value_key=e_k)) if event.source is not None and len(event.source) > 0: event_where.append(sh.multi_conditions(f"main.value ILIKE %(custom{i})s", event.source, @@ -617,53 +618,53 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, full_args = {**full_args, **sh.multi_values(event.source, value_key=f"custom{i}")} else: - event_from = event_from % f"{events.EventType.INPUT_MOBILE.table} AS main " + event_from = event_from % f"events_ios.inputs AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.INPUT_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.label {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.LOCATION.ui_type: + elif event_type == schemas.EventType.LOCATION: if platform == "web": - event_from = event_from % f"{events.EventType.LOCATION.table} AS main " + event_from = event_from % f"events.pages AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.LOCATION.column} {op} %({e_k})s", + sh.multi_conditions(f"main.path {op} %({e_k})s", event.value, value_key=e_k)) else: - event_from = event_from % f"{events.EventType.VIEW_MOBILE.table} AS main " + event_from = event_from % f"events_ios.views AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.VIEW_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.name {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.CUSTOM.ui_type: - event_from = event_from % f"{events.EventType.CUSTOM.table} AS main " + elif event_type == schemas.EventType.CUSTOM: + event_from = event_from % f"events_common.customs AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.CUSTOM.column} {op} %({e_k})s", event.value, + sh.multi_conditions(f"main.name {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.REQUEST.ui_type: - event_from = event_from % f"{events.EventType.REQUEST.table} AS main " + elif event_type == schemas.EventType.REQUEST: + event_from = event_from % f"events_common.requests AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.REQUEST.column} {op} %({e_k})s", event.value, + sh.multi_conditions(f"main.path {op} %({e_k})s", event.value, value_key=e_k)) - # elif event_type == events.event_type.GRAPHQL.ui_type: + # elif event_type == schemas.event_type.GRAPHQL: # event_from = event_from % f"{events.event_type.GRAPHQL.table} AS main " # if not is_any: # event_where.append( # _multiple_conditions(f"main.{events.event_type.GRAPHQL.column} {op} %({e_k})s", event.value, # value_key=e_k)) - elif event_type == events.EventType.STATEACTION.ui_type: - event_from = event_from % f"{events.EventType.STATEACTION.table} AS main " + elif event_type == schemas.EventType.STATE_ACTION: + event_from = event_from % f"events.state_actions AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.STATEACTION.column} {op} %({e_k})s", + sh.multi_conditions(f"main.name {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.ERROR.ui_type: - event_from = event_from % f"{events.EventType.ERROR.table} AS main INNER JOIN public.errors AS main1 USING(error_id)" + elif event_type == schemas.EventType.ERROR: + event_from = event_from % f"events.errors AS main INNER JOIN public.errors AS main1 USING(error_id)" event.source = list(set(event.source)) if not is_any and event.value not in [None, "*", ""]: event_where.append( @@ -674,59 +675,59 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, # ----- Mobile - elif event_type == events.EventType.CLICK_MOBILE.ui_type: - event_from = event_from % f"{events.EventType.CLICK_MOBILE.table} AS main " + elif event_type == schemas.EventType.CLICK_MOBILE: + event_from = event_from % f"events_ios.taps AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.CLICK_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.label {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.INPUT_MOBILE.ui_type: - event_from = event_from % f"{events.EventType.INPUT_MOBILE.table} AS main " + elif event_type == schemas.EventType.INPUT_MOBILE: + event_from = event_from % f"events_ios.inputs AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.INPUT_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.label {op} %({e_k})s", event.value, value_key=e_k)) if event.source is not None and len(event.source) > 0: event_where.append(sh.multi_conditions(f"main.value ILIKE %(custom{i})s", event.source, value_key="custom{i}")) full_args = {**full_args, **sh.multi_values(event.source, f"custom{i}")} - elif event_type == events.EventType.VIEW_MOBILE.ui_type: - event_from = event_from % f"{events.EventType.VIEW_MOBILE.table} AS main " + elif event_type == schemas.EventType.VIEW_MOBILE: + event_from = event_from % f"events_ios.views AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.VIEW_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.name {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.CUSTOM_MOBILE.ui_type: - event_from = event_from % f"{events.EventType.CUSTOM_MOBILE.table} AS main " + elif event_type == schemas.EventType.CUSTOM_MOBILE: + event_from = event_from % f"events_common.customs AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.CUSTOM_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.name {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.REQUEST_MOBILE.ui_type: - event_from = event_from % f"{events.EventType.REQUEST_MOBILE.table} AS main " + elif event_type == schemas.EventType.REQUEST_MOBILE: + event_from = event_from % f"events_common.requests AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.REQUEST_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.path {op} %({e_k})s", event.value, value_key=e_k)) - elif event_type == events.EventType.CRASH_MOBILE.ui_type: - event_from = event_from % f"{events.EventType.CRASH_MOBILE.table} AS main INNER JOIN public.crashes_ios AS main1 USING(crash_ios_id)" + elif event_type == schemas.EventType.ERROR_MOBILE: + event_from = event_from % f"events_common.crashes AS main INNER JOIN public.crashes_ios AS main1 USING(crash_ios_id)" if not is_any and event.value not in [None, "*", ""]: event_where.append( sh.multi_conditions(f"(main1.reason {op} %({e_k})s OR main1.name {op} %({e_k})s)", event.value, value_key=e_k)) - elif event_type == events.EventType.SWIPE_MOBILE.ui_type and platform != "web": - event_from = event_from % f"{events.EventType.SWIPE_MOBILE.table} AS main " + elif event_type == schemas.EventType.SWIPE_MOBILE and platform != "web": + event_from = event_from % f"events_ios.swipes AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.SWIPE_MOBILE.column} {op} %({e_k})s", + sh.multi_conditions(f"main.label {op} %({e_k})s", event.value, value_key=e_k)) elif event_type == schemas.PerformanceEventType.FETCH_FAILED: - event_from = event_from % f"{events.EventType.REQUEST.table} AS main " + event_from = event_from % f"events_common.requests AS main " if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.REQUEST.column} {op} %({e_k})s", + sh.multi_conditions(f"main.path {op} %({e_k})s", event.value, value_key=e_k)) col = performance_event.get_col(event_type) colname = col["column"] @@ -751,7 +752,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, schemas.PerformanceEventType.LOCATION_AVG_CPU_LOAD, schemas.PerformanceEventType.LOCATION_AVG_MEMORY_USAGE ]: - event_from = event_from % f"{events.EventType.LOCATION.table} AS main " + event_from = event_from % f"events.pages AS main " col = performance_event.get_col(event_type) colname = col["column"] tname = "main" @@ -762,7 +763,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, f"{tname}.timestamp <= %(endDate)s"] if not is_any: event_where.append( - sh.multi_conditions(f"main.{events.EventType.LOCATION.column} {op} %({e_k})s", + sh.multi_conditions(f"main.path {op} %({e_k})s", event.value, value_key=e_k)) e_k += "_custom" full_args = {**full_args, **sh.multi_values(event.source, value_key=e_k)} @@ -772,7 +773,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, event.source, value_key=e_k)) elif event_type == schemas.EventType.REQUEST_DETAILS: - event_from = event_from % f"{events.EventType.REQUEST.table} AS main " + event_from = event_from % f"events_common.requests AS main " apply = False for j, f in enumerate(event.filters): is_any = sh.isAny_opreator(f.operator) @@ -784,7 +785,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, full_args = {**full_args, **sh.multi_values(f.value, value_key=e_k_f)} if f.type == schemas.FetchFilterType.FETCH_URL: event_where.append( - sh.multi_conditions(f"main.{events.EventType.REQUEST.column} {op} %({e_k_f})s::text", + sh.multi_conditions(f"main.path {op} %({e_k_f})s::text", f.value, value_key=e_k_f)) apply = True elif f.type == schemas.FetchFilterType.FETCH_STATUS_CODE: @@ -816,7 +817,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, if not apply: continue elif event_type == schemas.EventType.GRAPHQL: - event_from = event_from % f"{events.EventType.GRAPHQL.table} AS main " + event_from = event_from % f"events.graphql AS main " for j, f in enumerate(event.filters): is_any = sh.isAny_opreator(f.operator) if is_any or len(f.value) == 0: @@ -827,7 +828,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, full_args = {**full_args, **sh.multi_values(f.value, value_key=e_k_f)} if f.type == schemas.GraphqlFilterType.GRAPHQL_NAME: event_where.append( - sh.multi_conditions(f"main.{events.EventType.GRAPHQL.column} {op} %({e_k_f})s", f.value, + sh.multi_conditions(f"main.name {op} %({e_k_f})s", f.value, value_key=e_k_f)) elif f.type == schemas.GraphqlFilterType.GRAPHQL_METHOD: event_where.append( @@ -908,7 +909,7 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, # b"s.user_os in ('Chrome OS','Fedora','Firefox OS','Linux','Mac OS X','Ubuntu','Windows')") if errors_only: - extra_from += f" INNER JOIN {events.EventType.ERROR.table} AS er USING (session_id) INNER JOIN public.errors AS ser USING (error_id)" + extra_from += f" INNER JOIN events.errors AS er USING (session_id) INNER JOIN public.errors AS ser USING (error_id)" extra_constraints.append("ser.source = 'js_exception'") extra_constraints.append("ser.project_id = %(project_id)s") # if error_status != schemas.ErrorStatus.all: @@ -984,9 +985,9 @@ def search_query_parts(data: schemas.SessionsSearchPayloadSchema, error_status, c.value = helper.values_for_operator(value=c.value, op=c.operator) full_args = {**full_args, **sh.multi_values(c.value, value_key=e_k)} - if c.type == events.EventType.LOCATION.ui_type: + if c.type == schemas.EventType.LOCATION: _extra_or_condition.append( - sh.multi_conditions(f"ev.{events.EventType.LOCATION.column} {op} %({e_k})s", + sh.multi_conditions(f"ev.path {op} %({e_k})s", c.value, value_key=e_k)) else: logger.warning(f"unsupported extra_event type:${c.type}") @@ -1044,18 +1045,15 @@ def get_user_sessions(project_id, user_id, start_date, end_date): def get_session_user(project_id, user_id): with pg_client.PostgresClient() as cur: query = cur.mogrify( - """\ - SELECT - user_id, - count(*) as session_count, - max(start_ts) as last_seen, - min(start_ts) as first_seen - FROM - "public".sessions - WHERE - project_id = %(project_id)s - AND user_id = %(userId)s - AND duration is not null + """ \ + SELECT user_id, + count(*) as session_count, + max(start_ts) as last_seen, + min(start_ts) as first_seen + FROM "public".sessions + WHERE project_id = %(project_id)s + AND user_id = %(userId)s + AND duration is not null GROUP BY user_id; """, {"project_id": project_id, "userId": user_id} @@ -1074,11 +1072,10 @@ def count_all(): def session_exists(project_id, session_id): with pg_client.PostgresClient() as cur: - query = cur.mogrify("""SELECT 1 - FROM public.sessions - WHERE session_id=%(session_id)s - AND project_id=%(project_id)s - LIMIT 1;""", + query = cur.mogrify("""SELECT 1 + FROM public.sessions + WHERE session_id = %(session_id)s + AND project_id = %(project_id)s LIMIT 1;""", {"project_id": project_id, "session_id": session_id}) cur.execute(query) row = cur.fetchone() diff --git a/api/chalicelib/core/sessions/sessions_replay.py b/api/chalicelib/core/sessions/sessions_replay.py index 24e8a9478..b0ea40613 100644 --- a/api/chalicelib/core/sessions/sessions_replay.py +++ b/api/chalicelib/core/sessions/sessions_replay.py @@ -1,6 +1,6 @@ import schemas -from chalicelib.core import events, metadata, events_mobile, \ - issues, assist, canvas, user_testing +from chalicelib.core import metadata, issues, assist, canvas, user_testing +from chalicelib.core.events import events, events_mobile from . import sessions_mobs, sessions_devtool from chalicelib.core.errors.modules import errors_helper from chalicelib.utils import pg_client, helper diff --git a/api/env.default b/api/env.default index 383e74273..6c53a6b12 100644 --- a/api/env.default +++ b/api/env.default @@ -75,4 +75,5 @@ EXP_AUTOCOMPLETE=true EXP_ALERTS=true EXP_ERRORS_SEARCH=true EXP_METRICS=true -EXP_SESSIONS_SEARCH=true \ No newline at end of file +EXP_SESSIONS_SEARCH=true +EXP_EVENTS=true \ No newline at end of file diff --git a/api/env.dev b/api/env.dev index 74f9f8e1f..9183efad6 100644 --- a/api/env.dev +++ b/api/env.dev @@ -68,4 +68,5 @@ EXP_CH_DRIVER=true EXP_AUTOCOMPLETE=true EXP_ALERTS=true EXP_ERRORS_SEARCH=true -EXP_METRICS=true \ No newline at end of file +EXP_METRICS=true +EXP_EVENTS=true \ No newline at end of file diff --git a/ee/api/.gitignore b/ee/api/.gitignore index d5392c84d..7ad13e838 100644 --- a/ee/api/.gitignore +++ b/ee/api/.gitignore @@ -201,8 +201,7 @@ Pipfile.lock /chalicelib/core/metrics/heatmaps /chalicelib/core/metrics/product_analytics /chalicelib/core/metrics/product_anaytics2.py -/chalicelib/core/events.py -/chalicelib/core/events_mobile.py +/chalicelib/core/events /chalicelib/core/feature_flags.py /chalicelib/core/issue_tracking/* /chalicelib/core/issues.py diff --git a/ee/api/clean-dev.sh b/ee/api/clean-dev.sh index 2e42c9d29..cc093f1a2 100755 --- a/ee/api/clean-dev.sh +++ b/ee/api/clean-dev.sh @@ -21,8 +21,7 @@ rm -rf ./chalicelib/core/metrics/dashboards.py rm -rf ./chalicelib/core/metrics/heatmaps rm -rf ./chalicelib/core/metrics/product_analytics rm -rf ./chalicelib/core/metrics/product_anaytics2.py -rm -rf ./chalicelib/core/events.py -rm -rf ./chalicelib/core/events_mobile.py +rm -rf ./chalicelib/core/events rm -rf ./chalicelib/core/feature_flags.py rm -rf ./chalicelib/core/issue_tracking rm -rf ./chalicelib/core/integrations_manager.py