From 91827b60ff86c95096180f624c019e0ceec09ec1 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Thu, 10 Nov 2022 20:23:06 +0100 Subject: [PATCH 1/5] feat(alerts): fixed query generator --- api/chalicelib/core/alerts_processor.py | 15 ++++++++++----- api/chalicelib/core/webhook.py | 4 ++-- ee/api/chalicelib/core/alerts_processor.py | 15 ++++++++++----- ee/api/chalicelib/core/webhook.py | 4 ++-- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/api/chalicelib/core/alerts_processor.py b/api/chalicelib/core/alerts_processor.py index 87599bbf3..c075d8df0 100644 --- a/api/chalicelib/core/alerts_processor.py +++ b/api/chalicelib/core/alerts_processor.py @@ -129,7 +129,7 @@ def Build(a): if a["seriesId"] is not None: q += f""" FROM ({subQ}) AS stat""" else: - q += f""" FROM ({subQ} {"AND timestamp >= % (startDate)s AND timestamp <= % (now)s" if is_ss else ""} + q += f""" FROM ({subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}) AS stat""" params = {**params, **full_args, "startDate": TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000} else: @@ -146,7 +146,7 @@ def Build(a): AND timestamp<=%(now)s {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < % (startDate)s AND timestamp >= % (timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() - 2 * a["options"]["currentPeriod"] * 60 * 1000 sub1 = f"SELECT (( {sub1} )-( {sub2} )) AS value" @@ -163,10 +163,10 @@ def Build(a): - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) \ * 60 * 1000} else: - sub1 = f"""{subQ} {"AND timestamp >= % (startDate)s AND timestamp <= % (now)s" if is_ss else ""} + sub1 = f"""{subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < % (startDate)s AND timestamp >= % (timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() \ - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) * 60 * 1000 @@ -184,7 +184,12 @@ def process(): if can_check(alert): logging.info(f"Querying alertId:{alert['alertId']} name: {alert['name']}") query, params = Build(alert) - query = cur.mogrify(query, params) + try: + query = cur.mogrify(query, params) + except Exception as e: + logging.error(f"!!!Error while building alert query for alertId:{alert['alertId']}") + logging.error(e) + continue logging.debug(alert) logging.debug(query) try: diff --git a/api/chalicelib/core/webhook.py b/api/chalicelib/core/webhook.py index d7f8bf671..d74271d58 100644 --- a/api/chalicelib/core/webhook.py +++ b/api/chalicelib/core/webhook.py @@ -160,8 +160,8 @@ def __trigger(hook, data): r = requests.post(url=hook["endpoint"], json=data, headers=headers) if r.status_code != 200: - logging.error("=======> webhook: something went wrong") - logging.error(r) + logging.error("=======> webhook: something went wrong for:") + logging.error(hook) logging.error(r.status_code) logging.error(r.text) return diff --git a/ee/api/chalicelib/core/alerts_processor.py b/ee/api/chalicelib/core/alerts_processor.py index be7f10f89..55e330df9 100644 --- a/ee/api/chalicelib/core/alerts_processor.py +++ b/ee/api/chalicelib/core/alerts_processor.py @@ -134,7 +134,7 @@ def Build(a): if a["seriesId"] is not None: q += f""" FROM ({subQ}) AS stat""" else: - q += f""" FROM ({subQ} {"AND timestamp >= % (startDate)s AND timestamp <= % (now)s" if is_ss else ""} + q += f""" FROM ({subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}) AS stat""" params = {**params, **full_args, "startDate": TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000} else: @@ -151,7 +151,7 @@ def Build(a): AND timestamp<=%(now)s {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < % (startDate)s AND timestamp >= % (timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() - 2 * a["options"]["currentPeriod"] * 60 * 1000 sub1 = f"SELECT (( {sub1} )-( {sub2} )) AS value" @@ -168,10 +168,10 @@ def Build(a): - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) \ * 60 * 1000} else: - sub1 = f"""{subQ} {"AND timestamp >= % (startDate)s AND timestamp <= % (now)s" if is_ss else ""} + sub1 = f"""{subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < % (startDate)s AND timestamp >= % (timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() \ - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) * 60 * 1000 @@ -189,7 +189,12 @@ def process(): if can_check(alert): logging.info(f"Querying alertId:{alert['alertId']} name: {alert['name']}") query, params = Build(alert) - query = cur.mogrify(query, params) + try: + query = cur.mogrify(query, params) + except Exception as e: + logging.error(f"!!!Error while building alert query for alertId:{alert['alertId']}") + logging.error(e) + continue logging.debug(alert) logging.debug(query) try: diff --git a/ee/api/chalicelib/core/webhook.py b/ee/api/chalicelib/core/webhook.py index fdec148dc..4ef0be6a9 100644 --- a/ee/api/chalicelib/core/webhook.py +++ b/ee/api/chalicelib/core/webhook.py @@ -166,8 +166,8 @@ def __trigger(hook, data): r = requests.post(url=hook["endpoint"], json=data, headers=headers) if r.status_code != 200: - logging.error("=======> webhook: something went wrong") - logging.error(r) + logging.error("=======> webhook: something went wrong for:") + logging.error(hook) logging.error(r.status_code) logging.error(r.text) return From 67cdd2cfd98d20752c738272b289b17447b2cdb9 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Thu, 10 Nov 2022 20:49:50 +0100 Subject: [PATCH 2/5] feat(alerts): fixed query generator --- api/chalicelib/core/alerts_processor.py | 8 ++++---- ee/api/chalicelib/core/alerts_processor.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/chalicelib/core/alerts_processor.py b/api/chalicelib/core/alerts_processor.py index c075d8df0..89c3d58f3 100644 --- a/api/chalicelib/core/alerts_processor.py +++ b/api/chalicelib/core/alerts_processor.py @@ -129,7 +129,7 @@ def Build(a): if a["seriesId"] is not None: q += f""" FROM ({subQ}) AS stat""" else: - q += f""" FROM ({subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} + q += f""" FROM ({subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if not is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}) AS stat""" params = {**params, **full_args, "startDate": TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000} else: @@ -146,7 +146,7 @@ def Build(a): AND timestamp<=%(now)s {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if not is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() - 2 * a["options"]["currentPeriod"] * 60 * 1000 sub1 = f"SELECT (( {sub1} )-( {sub2} )) AS value" @@ -163,10 +163,10 @@ def Build(a): - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) \ * 60 * 1000} else: - sub1 = f"""{subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} + sub1 = f"""{subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if not is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if not is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() \ - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) * 60 * 1000 diff --git a/ee/api/chalicelib/core/alerts_processor.py b/ee/api/chalicelib/core/alerts_processor.py index 55e330df9..1870c1f6c 100644 --- a/ee/api/chalicelib/core/alerts_processor.py +++ b/ee/api/chalicelib/core/alerts_processor.py @@ -134,7 +134,7 @@ def Build(a): if a["seriesId"] is not None: q += f""" FROM ({subQ}) AS stat""" else: - q += f""" FROM ({subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} + q += f""" FROM ({subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if not is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}) AS stat""" params = {**params, **full_args, "startDate": TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000} else: @@ -151,7 +151,7 @@ def Build(a): AND timestamp<=%(now)s {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if not is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() - 2 * a["options"]["currentPeriod"] * 60 * 1000 sub1 = f"SELECT (( {sub1} )-( {sub2} )) AS value" @@ -168,10 +168,10 @@ def Build(a): - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) \ * 60 * 1000} else: - sub1 = f"""{subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if is_ss else ""} + sub1 = f"""{subQ} {"AND timestamp >= %(startDate)s AND timestamp <= %(now)s" if not is_ss else ""} {"AND start_ts >= %(startDate)s AND start_ts <= %(now)s" if j_s else ""}""" params["startDate"] = TimeUTC.now() - a["options"]["currentPeriod"] * 60 * 1000 - sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if is_ss else ""} + sub2 = f"""{subQ} {"AND timestamp < %(startDate)s AND timestamp >= %(timestamp_sub2)s" if not is_ss else ""} {"AND start_ts < %(startDate)s AND start_ts >= %(timestamp_sub2)s" if j_s else ""}""" params["timestamp_sub2"] = TimeUTC.now() \ - (a["options"]["currentPeriod"] + a["options"]["currentPeriod"]) * 60 * 1000 From 3296c7a8917e53b203afac9fbcb4802cb0b0343e Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Thu, 10 Nov 2022 20:58:13 +0100 Subject: [PATCH 3/5] feat(chalice): pg_client allow rollback on recreation --- api/chalicelib/core/alerts_processor.py | 2 +- api/chalicelib/utils/pg_client.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/api/chalicelib/core/alerts_processor.py b/api/chalicelib/core/alerts_processor.py index 89c3d58f3..4cf3fc507 100644 --- a/api/chalicelib/core/alerts_processor.py +++ b/api/chalicelib/core/alerts_processor.py @@ -203,7 +203,7 @@ def process(): logging.error(query) print("------------") logging.error(e) - cur = cur.recreate() + cur = cur.recreate(rollback=True) if len(notifications) > 0: cur.execute( cur.mogrify(f"""UPDATE public.Alerts diff --git a/api/chalicelib/utils/pg_client.py b/api/chalicelib/utils/pg_client.py index 1c4ef8560..69a5b5a8b 100644 --- a/api/chalicelib/utils/pg_client.py +++ b/api/chalicelib/utils/pg_client.py @@ -136,7 +136,12 @@ class PostgresClient: and not self.unlimited_query: postgreSQL_pool.putconn(self.connection) - def recreate_cursor(self): + def recreate_cursor(self, rollback=False): + if rollback: + try: + self.connection.rollback() + except Exception as error: + logging.error("Error while rollbacking connection for recreation", error) try: self.cursor.close() except Exception as error: From c9c929d067e604c1a4c059c74809c58ed88953ef Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Mon, 14 Nov 2022 12:32:06 +0100 Subject: [PATCH 4/5] feat(chalice): log funnel query's exceptions --- api/chalicelib/core/significance.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/api/chalicelib/core/significance.py b/api/chalicelib/core/significance.py index 2276694a7..2abd87cf7 100644 --- a/api/chalicelib/core/significance.py +++ b/api/chalicelib/core/significance.py @@ -222,11 +222,20 @@ def get_stages_and_events(filter_d, project_id) -> List[RealDictRow]: params = {"project_id": project_id, "startTimestamp": filter_d["startDate"], "endTimestamp": filter_d["endDate"], "issueTypes": tuple(filter_issues), **values} with pg_client.PostgresClient() as cur: + query = cur.mogrify(n_stages_query, params) # print("---------------------------------------------------") - # print(cur.mogrify(n_stages_query, params)) + # print(query) # print("---------------------------------------------------") - cur.execute(cur.mogrify(n_stages_query, params)) - rows = cur.fetchall() + try: + cur.execute(query) + rows = cur.fetchall() + except Exception as err: + print("--------- FUNNEL SEARCH QUERY EXCEPTION -----------") + print(query.decode('UTF-8')) + print("--------- PAYLOAD -----------") + print(filter_d) + print("--------------------") + raise err return rows From 062aaf60d35b0aaf468a95a0d2d1d03b9ad3659b Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Mon, 14 Nov 2022 12:54:40 +0100 Subject: [PATCH 5/5] feat(chalice): log series query's exceptions --- api/chalicelib/core/sessions.py | 10 +++++++++- ee/api/chalicelib/core/sessions.py | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/api/chalicelib/core/sessions.py b/api/chalicelib/core/sessions.py index b7b0d7bd3..fcea8621d 100644 --- a/api/chalicelib/core/sessions.py +++ b/api/chalicelib/core/sessions.py @@ -332,7 +332,15 @@ def search2_series(data: schemas.SessionsSearchPayloadSchema, project_id: int, d # print("--------------------") # print(main_query) # print("--------------------") - cur.execute(main_query) + try: + cur.execute(main_query) + except Exception as err: + print("--------- SESSIONS-SERIES QUERY EXCEPTION -----------") + print(main_query.decode('UTF-8')) + print("--------- PAYLOAD -----------") + print(data.json()) + print("--------------------") + raise err if view_type == schemas.MetricTimeseriesViewType.line_chart: sessions = cur.fetchall() else: diff --git a/ee/api/chalicelib/core/sessions.py b/ee/api/chalicelib/core/sessions.py index edb951cd1..8c9eaf006 100644 --- a/ee/api/chalicelib/core/sessions.py +++ b/ee/api/chalicelib/core/sessions.py @@ -336,7 +336,15 @@ def search2_series(data: schemas.SessionsSearchPayloadSchema, project_id: int, d # print("--------------------") # print(main_query) # print("--------------------") - cur.execute(main_query) + try: + cur.execute(main_query) + except Exception as err: + print("--------- SESSIONS-SERIES QUERY EXCEPTION -----------") + print(main_query.decode('UTF-8')) + print("--------- PAYLOAD -----------") + print(data.json()) + print("--------------------") + raise err if view_type == schemas.MetricTimeseriesViewType.line_chart: sessions = cur.fetchall() else: