from logging import Formatter, StreamHandler, Logger, DEBUG, INFO, WARNING, ERROR from logging.handlers import TimedRotatingFileHandler from os import makedirs from os.path import dirname from aiohttp import ClientSession, TraceRequestStartParams, FormData from multidict import CIMultiDict from .config import Config def mkdir_p(path): try: makedirs(dirname(path), exist_ok=True) except TypeError: makedirs(dirname(path)) class BotLogger: log: Logger def __init__(self, config: Config): formatter = Formatter( "[%(name)s] [%(levelname)s] [%(asctime)s] [%(filename)s:%(lineno)d]: %(message)s", "%H:%M:%S %d.%m.%Y", ) mkdir_p(config.logs.path) level = DEBUG if config.debug else INFO BotLogger.log = Logger(config.logs.name or "KuroCore", level=level) console_handler = StreamHandler() console_handler.setFormatter(formatter) file_handler = TimedRotatingFileHandler( "logs/log.log", when="midnight", encoding="utf-8" ) file_handler.suffix = "%d.%m.%Y.log" file_handler.setFormatter(formatter) BotLogger.log.addHandler(console_handler) BotLogger.log.addHandler(file_handler) BotLogger.log.info("Logger initialized") class RequestLogger: log: Logger def __init__(self, config: Config) -> None: formatter = Formatter( '[%(name)s] [REQUEST] [%(asctime)s]: %(message)s', "%H:%M:%S %d.%m.%Y" ) mkdir_p(config.logs.path) RequestLogger.log = Logger(config.logs.name, level=DEBUG) console_handler = StreamHandler() console_handler.setFormatter(formatter) file_handler = TimedRotatingFileHandler(f'{config.logs.path}/requests.log', 'midnight') file_handler.suffix = "%d.%m.%Y.log" file_handler.setFormatter(formatter) if config.logs.console: RequestLogger.log.addHandler(console_handler) RequestLogger.log.addHandler(file_handler) RequestLogger.log.info("Request logger initialized") class ClientLogger: log: Logger def __init__(self, config: Config): formatter = Formatter( "[%(name)s] [CLIENT] [%(asctime)s]: %(message)s", "%H:%M:%S %d.%m.%Y", ) mkdir_p(config.logs.path) ClientLogger.log = Logger(config.logs.name, level=DEBUG) console_handler = StreamHandler() console_handler.setFormatter(formatter) file_handler = TimedRotatingFileHandler("logs/client.log", when="midnight", encoding="utf-8") file_handler.suffix = "%d.%m.%Y.log" file_handler.setFormatter(formatter) if config.logs.console: ClientLogger.log.addHandler(console_handler) ClientLogger.log.addHandler(file_handler) ClientLogger.log.info("Client logger initialized") @staticmethod def format_header(headers: CIMultiDict): out = [] for k, v in headers.items(): out.append(f'{k}:{v}') return f'<{", ".join(out)}>' @staticmethod async def on_request_start(session: ClientSession, context, params: TraceRequestStartParams): formatted_headers = ClientLogger.format_header(params.headers) ClientLogger.log.debug(f'request {params.method} {params.url} headers={formatted_headers}') class LoggingClientSession(ClientSession): async def _request(self, method, url, **kwargs): ClientLogger.log.debug(f'request <{method}> "{url}"') ClientLogger.log.debug(f' body: {kwargs}') return await super()._request(method, url, **kwargs)