From 0960b8979279a21332feffc61b5101e32d75ba0f Mon Sep 17 00:00:00 2001 From: Vyacheslav Zalygin Date: Mon, 30 Sep 2024 14:43:25 +0300 Subject: [PATCH] add forced logout and client handler errors metric --- src/client_handler.py | 50 ++++++++++++++++++++++++++++++++----------- src/metrics.py | 5 ++++- src/samoware_api.py | 1 - 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/client_handler.py b/src/client_handler.py index d54a8fe..bb9cea3 100644 --- a/src/client_handler.py +++ b/src/client_handler.py @@ -19,7 +19,14 @@ UnauthorizedError, ) from util import MessageSender -import metrics +from metrics import ( + login_metric, + logout_metric, + forced_logout_metric, + relogin_metric, + revalidation_metric, + client_handler_errors_metric, +) REVALIDATE_INTERVAL = timedelta(hours=5) SESSION_TOKEN_PATTERN = re.compile("^[0-9]{6}-[a-zA-Z0-9]{20}$") @@ -64,7 +71,7 @@ async def make_new( message_sender, db, Context(telegram_id, samoware_login) ) is_successful_login = await handler.login(samoware_password) - metrics.login_metric.labels(is_successful=is_successful_login).inc() + login_metric.labels(is_successful=is_successful_login).inc() if not is_successful_login: await message_sender(telegram_id, WRONG_CREDS_PROMPT, MARKDOWN_FORMAT) return None @@ -88,7 +95,7 @@ def get_polling_task(self) -> asyncio.Task: async def stop_handling(self) -> None: if not (self.polling_task.cancelled() or self.polling_task.done()): self.polling_task.cancel() - metrics.logout_metric.inc() + logout_metric.inc() await asyncio.wait([self.polling_task]) async def polling(self) -> None: @@ -124,30 +131,34 @@ async def polling(self) -> None: timezone.utc, ) < datetime.now(timezone.utc): is_successful_revalidation = await self.revalidate() - metrics.revalidation_metric.labels( + revalidation_metric.labels( is_successful=is_successful_revalidation ).inc() if not is_successful_revalidation: await self.can_not_revalidate() self.db.remove_client(self.context.telegram_id) + forced_logout_metric.inc() return retry_count = 0 except asyncio.CancelledError: return - except UnauthorizedError: + except UnauthorizedError as error: + client_handler_errors_metric.labels( + type=type(error).__name__ + ).inc() log.info(f"session for {self.context.samoware_login} expired") samoware_password = self.db.get_password(self.context.telegram_id) if samoware_password is None: await self.session_has_expired() self.db.remove_client(self.context.telegram_id) + forced_logout_metric.inc() return is_successful_relogin = await self.login(samoware_password) - metrics.relogin_metric.labels( - is_successful=is_successful_relogin - ).inc() + relogin_metric.labels(is_successful=is_successful_relogin).inc() if not is_successful_relogin: await self.can_not_relogin() self.db.remove_client(self.context.telegram_id) + forced_logout_metric.inc() return except ( aiohttp.ClientOSError @@ -155,13 +166,19 @@ async def polling(self) -> None: log.warning( f"retry_count={retry_count}. ClientOSError. Probably Broken pipe. Retrying in {HTTP_RETRY_DELAY_SEC} seconds. {str(error)}" ) + client_handler_errors_metric.labels( + type=type(error).__name__ + ).inc() retry_count += 1 await asyncio.sleep(HTTP_RETRY_DELAY_SEC) - except Exception: + except Exception as error: log.exception("exception in client_handler") log.warning( f"retry_count={retry_count}. Retrying longpolling for {self.context.samoware_login} in {HTTP_RETRY_DELAY_SEC} seconds..." ) + client_handler_errors_metric.labels( + type=type(error).__name__ + ).inc() retry_count += 1 await asyncio.sleep(HTTP_RETRY_DELAY_SEC) finally: @@ -182,16 +199,22 @@ async def login(self, samoware_password: str) -> bool: self.db.set_handler_context(self.context) log.info(f"successful login for user {self.context.samoware_login}") return True - except UnauthorizedError: + except UnauthorizedError as error: log.info(f"unsuccessful login for user {self.context.samoware_login}") + client_handler_errors_metric.labels( + type=type(error).__name__ + ).inc() return False except asyncio.CancelledError: log.info("login cancelled") return False - except Exception: + except Exception as error: log.exception( f"retry_count={retry_count}. exception on login. retrying in {HTTP_RETRY_DELAY_SEC}..." ) + client_handler_errors_metric.labels( + type=type(error).__name__ + ).inc() retry_count += 1 await asyncio.sleep(HTTP_RETRY_DELAY_SEC) @@ -213,8 +236,11 @@ async def revalidate(self) -> bool: self.db.set_handler_context(self.context) log.info(f"successful revalidation for user {self.context.samoware_login}") return True - except UnauthorizedError: + except UnauthorizedError as error: log.exception("UnauthorizedError on revalidation") + client_handler_errors_metric.labels( + type=type(error).__name__ + ).inc() return False async def can_not_revalidate(self): diff --git a/src/metrics.py b/src/metrics.py index 293b9fb..2133e06 100644 --- a/src/metrics.py +++ b/src/metrics.py @@ -16,7 +16,6 @@ sent_message_metric = Counter("sent_message", "Sent messages metric") # Samoware -unauthorized_metric = Counter("unauth", "Unathorized samowarium responses metric") samoware_response_status_code_metric = Counter( "samoware_response_sc", "Samoware reponses status code metric", labelnames=["sc"] ) @@ -30,3 +29,7 @@ "revalidation", "Revalidation events metric", labelnames=["is_successful"] ) logout_metric = Counter("logout", "Logout events metric") +forced_logout_metric = Counter("forced_logout", "Forced logout events metric") +client_handler_errors_metric = Counter( + "client_handler_error", "Client handler error events metric", labelnames=["type"] +) diff --git a/src/samoware_api.py b/src/samoware_api.py index 15b915e..1cc8435 100644 --- a/src/samoware_api.py +++ b/src/samoware_api.py @@ -213,7 +213,6 @@ async def longpoll_updates( log.warning( f"received 550 code in longPollUpdates - Samoware Unauthorized. response: {response_text}" ) - metrics.unauthorized_metric.inc() raise UnauthorizedError if response.status != 200: log.error(