From 0b9df71be97c41de4e4ea0acb16480481b72dfcf Mon Sep 17 00:00:00 2001 From: tpv Date: Wed, 24 Jun 2026 13:17:29 -0700 Subject: [PATCH] added logging rotators/json handler --- monitor_utils/config.py | 51 +++++++++++++++++++++++++++++++++++++++++ monitor_utils/runner.py | 7 ------ 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/monitor_utils/config.py b/monitor_utils/config.py index f474764..0d0aa4c 100644 --- a/monitor_utils/config.py +++ b/monitor_utils/config.py @@ -1,6 +1,8 @@ +import logging import json import pathlib from functools import cache +from logging.handlers import RotatingFileHandler from monitor_utils.constants import ( PROXIES_PATH, @@ -8,9 +10,58 @@ from monitor_utils.constants import ( DEVELOPMENT_MODE, PRODUCTION_BOT_TOKEN, DEVELOPMENT_BOT_TOKEN, + LOGGING_LEVEL, DevelopmentMode, ) +RESERVED = frozenset(logging.LogRecord("", 0, "", 0, "", (), None).__dict__) + + +class JSONFormatter(logging.Formatter): + def format(self, record: logging.LogRecord) -> str: + payload = { + "time": self.formatTime(record), + "level": record.levelname, + "logger": record.name, + "function": record.funcName, + "message": record.getMessage(), + } + for key, value in record.__dict__.items(): + if key not in RESERVED and not key.startswith("_"): + payload[key] = value + + if record.exc_info: + payload["exc"] = self.formatException(record.exc_info) + + return json.dumps(payload) + + +def configure_logging(monitor_name: str): + handler = logging.StreamHandler() + handler.setFormatter(JSONFormatter()) + + def inject_monitor(record: logging.LogRecord) -> bool: + record.monitor = monitor_name + return True + + handler.addFilter(inject_monitor) + file_handler = RotatingFileHandler( + f"/logs/{monitor_name}.jsonl", + maxBytes=10 * 1024 * 1024, + backupCount=5, + ) + file_handler.setFormatter(JSONFormatter()) + file_handler.addFilter(inject_monitor) + + root = logging.getLogger() + root.handlers.clear() + root.setLevel(LOGGING_LEVEL) + root.addHandler(handler) + root.addHandler(file_handler) + + logging.getLogger("aiohttp").setLevel(logging.WARNING) + logging.getLogger("pymongo").setLevel(logging.WARNING) + def is_production(override_production=False) -> bool: if override_production: diff --git a/monitor_utils/runner.py b/monitor_utils/runner.py index bea0bdd..b148c89 100644 --- a/monitor_utils/runner.py +++ b/monitor_utils/runner.py @@ -27,13 +27,6 @@ from monitor_utils.database import get_collection LOGGER = logging.getLogger(__name__) -def configure_logging(): - logging.basicConfig( - level=LOGGING_LEVEL, - format="%(asctime)s - %(levelname)s - %(module)s - %(funcName)s - %(message)s", - ) - - def setup_config( monitor_name: str, override_production=False ) -> tuple[list[str], dict, AsyncIOMotorCollection]: