Coverage for chalicelib/core/issues/issues_ch.py: 0%
34 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:56 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:56 +0000
1from chalicelib.utils import ch_client, helper
2import datetime
3from chalicelib.utils.exp_ch_helper import add_timestamp
6def get_issue(project_id, issue_id):
7 with ch_client.ClickHouseClient() as cur:
8 query = cur.format(query=""" \
9 SELECT *
10 FROM product_analytics.events
11 WHERE project_id = %(project_id)s
12 AND issue_id = %(issue_id)s;""",
13 parameters={"project_id": project_id, "issue_id": issue_id})
14 data = cur.execute(query=query)
15 if data is not None and len(data) > 0:
16 data = data[0]
17 data["title"] = helper.get_issue_title(data["type"])
18 return helper.dict_to_camel_case(data)
21def get_by_session_id(session_id, project_id, issue_type=None):
22 with ch_client.ClickHouseClient() as cur:
23 query = cur.format(query=f"""\
24 SELECT DISTINCT ON (events.created_at, issue_id) events.created_at,
25 issue_id,
26 issue_type,
27 context_string
28 FROM product_analytics.events
29 INNER JOIN experimental.issues ON (events.issue_id = issues.issue_id)
30 WHERE session_id = %(session_id)s
31 AND events.project_id= %(project_id)s
32 AND issues.project_id= %(project_id)s
33 AND `$event_name`='ISSUE'
34 AND {"events.issue_type = %(type)s AND issues.type = %(type)s" if issue_type is not None else "issue_type = 'incident'"}
35 ORDER BY created_at;""",
36 parameters={"session_id": session_id, "project_id": project_id, "type": issue_type})
37 rows = cur.execute(query)
38 # rows = explode_dproperties(rows)
39 rows = helper.list_to_camel_case(rows)
40 rows = add_timestamp(rows)
41 return rows
44# To reduce the number of issues in the replay;
45# will be removed once we agree on how to show issues
46def reduce_issues(issues_list):
47 if issues_list is None:
48 return None
49 i = 0
50 # remove same-type issues if the time between them is <2s
51 while i < len(issues_list) - 1:
52 for j in range(i + 1, len(issues_list)):
53 if issues_list[i]["issueType"] == issues_list[j]["issueType"]:
54 break
55 else:
56 i += 1
57 break
59 if issues_list[i]["createdAt"] - issues_list[j]["createdAt"] < datetime.timedelta(seconds=2):
60 issues_list.pop(j)
61 else:
62 i += 1
64 return issues_list
67def get_all_types():
68 return {
69 "js_exception": {
70 "type": "js_exception",
71 "visible": True,
72 "order": 0,
73 "name": "Errors",
74 "autoCaptured": True
75 },
76 "bad_request": {
77 "type": "bad_request",
78 "visible": True,
79 "order": 1,
80 "name": "Bad Requests",
81 "autoCaptured": True
82 },
83 "missing_resource": {
84 "type": "missing_resource",
85 "visible": True,
86 "order": 2,
87 "name": "Missing Images",
88 "autoCaptured": True
89 },
90 "click_rage": {
91 "type": "click_rage",
92 "visible": True,
93 "order": 3,
94 "name": "Click Rage",
95 "autoCaptured": True
96 },
97 "dead_click": {
98 "type": "dead_click",
99 "visible": True,
100 "order": 4,
101 "name": "Dead Clicks",
102 "autoCaptured": True
103 },
104 "memory": {
105 "type": "memory",
106 "visible": True,
107 "order": 5,
108 "name": "High Memory",
109 "autoCaptured": True
110 },
111 "cpu": {
112 "type": "cpu",
113 "visible": True,
114 "order": 6,
115 "name": "High CPU",
116 "autoCaptured": True
117 },
118 "crash": {
119 "type": "crash",
120 "visible": True,
121 "order": 7,
122 "name": "Crashes",
123 "autoCaptured": True
124 },
125 "incident": {
126 "type": "incident",
127 "visible": True,
128 "order": 8,
129 "name": "Incident",
130 "autoCaptured": False
131 }
132 }