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

1from chalicelib.utils import ch_client, helper 

2import datetime 

3from chalicelib.utils.exp_ch_helper import add_timestamp 

4 

5 

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) 

19 

20 

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 

42 

43 

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 

58 

59 if issues_list[i]["createdAt"] - issues_list[j]["createdAt"] < datetime.timedelta(seconds=2): 

60 issues_list.pop(j) 

61 else: 

62 i += 1 

63 

64 return issues_list 

65 

66 

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 }