diff --git a/libs/boot_utils/__init__.py b/libs/boot_utils/__init__.py index ad9e195cc..845bb3c52 100644 --- a/libs/boot_utils/__init__.py +++ b/libs/boot_utils/__init__.py @@ -1,13 +1,12 @@ from .args_parser import setup_start_parser from .load_cogs import load_cogs from .load_sql_connection import load_sql_connection -from .logs_setup import set_beta_logs, setup_bot_logger, setup_database_logger +from .logs_setup import set_beta_logs, setup_logger __all__ = [ "setup_start_parser", "load_cogs", "load_sql_connection", - "setup_bot_logger", - "setup_database_logger", + "setup_logger", "set_beta_logs" ] diff --git a/libs/boot_utils/logs_setup.py b/libs/boot_utils/logs_setup.py index 3b9622f4a..7a2858cb3 100644 --- a/libs/boot_utils/logs_setup.py +++ b/libs/boot_utils/logs_setup.py @@ -3,10 +3,10 @@ from logging.handlers import RotatingFileHandler -def setup_bot_logger(): - """Create the logger module for the bot, used for logs""" - log = logging.getLogger("runner") - log_format = logging.Formatter("[{asctime}] {levelname} {name}: {message}", datefmt="%Y-%m-%d %H:%M:%S", style='{') +def setup_logger(): + """Create the logger module for the whole bot""" + bot_logger = logging.getLogger("bot") + log_format = logging.Formatter("[{asctime}] {levelname:<7} [{name}]: {message}", datefmt="%Y-%m-%d %H:%M:%S", style='{') # DEBUG logs to a file file_handler = RotatingFileHandler("logs/debug.log", maxBytes=1e6, backupCount=2, delay=True) @@ -21,35 +21,47 @@ def setup_bot_logger(): stream_handler.set_name("console") # add handlers to the logger - log.addHandler(file_handler) - log.addHandler(stream_handler) + bot_logger.addHandler(file_handler) + bot_logger.addHandler(stream_handler) # set the logging level to DEBUG (so handlers can filter it) - log.setLevel(logging.DEBUG) - return log + bot_logger.setLevel(logging.DEBUG) -def setup_database_logger(): - "Create the logger module for database access" - log = logging.getLogger("database") - log_format = logging.Formatter("%(asctime)s %(levelname)s: [SQL] %(message)s", datefmt="[%d/%m/%Y %H:%M]") - file_handler = RotatingFileHandler("logs/sql-debug.log", maxBytes=2e6, backupCount=2, delay=True) + # add specific logger for database logs + _setup_database_logger() + + return bot_logger + +def _setup_database_logger(): + "Create the logger module for the database, as a sub-logger of the bot logger" + db_logger = logging.getLogger("bot.db") + log_format = logging.Formatter("[{asctime}] {levelname:<7} [{name}]: {message}", datefmt="%Y-%m-%d %H:%M:%S", style='{') + # DEBUG logs to a file + file_handler = RotatingFileHandler("logs/sql-debug.log", maxBytes=2e6, backupCount=2, delay=True) file_handler.setLevel(logging.DEBUG) file_handler.setFormatter(log_format) + file_handler.set_name("file") + # INFO logs to console stream_handler = logging.StreamHandler(sys.stdout) stream_handler.setLevel(logging.INFO) stream_handler.setFormatter(log_format) + stream_handler.set_name("console") - log.addHandler(file_handler) - log.addHandler(stream_handler) - log.setLevel(logging.DEBUG) - return log + # add handlers to the logger + db_logger.addHandler(file_handler) + db_logger.addHandler(stream_handler) + + # set the logging level to DEBUG (so handlers can filter it) + db_logger.setLevel(logging.DEBUG) + # don't propagate the logs to the bot logger (so DEBUG logs don't appear in the console) + db_logger.propagate = False def set_beta_logs(): "Edit the logging handlers to be more verbose in console, when the beta bot is used" # set the console logger to DEBUG - bot_logger = logging.getLogger("runner") + bot_logger = logging.getLogger("bot") for handler in bot_logger.handlers: if handler.name == "console": handler.setLevel(logging.DEBUG) diff --git a/libs/bot_classes/axobot.py b/libs/bot_classes/axobot.py index 12f3bf9f2..79f5c8527 100644 --- a/libs/bot_classes/axobot.py +++ b/libs/bot_classes/axobot.py @@ -70,7 +70,7 @@ def __init__(self, case_insensitive: bool = None, status: discord.Status = None, self.beta = beta # if the bot is in beta mode self.entity_id: int = 0 # ID of the bot for the statistics database self.database_keys = get_database_connection() # credentials for the database - self.log = logging.getLogger("runner") # logs module + self.log = logging.getLogger("bot") # logs module self._cnx = [[None, 0], [None, 0], [None, 0]] # database connections self.xp_enabled: bool = True # if xp is enabled self.rss_enabled: bool = True # if rss is enabled diff --git a/libs/database.py b/libs/database.py index fdd60b9d0..b8a6a5248 100644 --- a/libs/database.py +++ b/libs/database.py @@ -1,13 +1,14 @@ import logging import sys from types import GeneratorType -from typing import Union, TYPE_CHECKING +from typing import TYPE_CHECKING, Union + +from mysql.connector import errors +from mysql.connector.connection import MySQLConnection, MySQLCursor +from mysql.connector.cursor import RE_PY_PARAM, _bytestr_format_dict, _ParamSubstitutor if TYPE_CHECKING: from mysql.connector.connection_cext import CMySQLConnection, CMySQLCursor -from mysql.connector.connection import MySQLConnection, MySQLCursor -from mysql.connector.cursor import _bytestr_format_dict, _ParamSubstitutor, RE_PY_PARAM -from mysql.connector import errors def create_database_query(cnx_axobot: Union[MySQLConnection, 'CMySQLConnection']): @@ -27,6 +28,7 @@ def __init__(self, query: str, args: Union[tuple, dict] = None, *, self.returnrowcount = returnrowcount self.astuple = astuple self.cursor: Union[MySQLCursor, 'CMySQLCursor'] = None + self.log = logging.getLogger("bot.db") async def _format_query(self): if isinstance(self.cursor, MySQLCursor): @@ -97,12 +99,12 @@ async def __aenter__(self) -> Union[int, list[dict], dict]: ) query_for_logs = await self._format_query() - logging.getLogger("database").debug("%s", query_for_logs) + self.log.debug("%s", query_for_logs) try: execute_result = self.cursor.execute(self.query, self.args, multi=self.multi) except errors.ProgrammingError as err: - logging.getLogger("database").error("%s", self.cursor._executed, exc_info=True) + self.log.error("%s", self.cursor._executed, exc_info=True) await self.__aexit__(*sys.exc_info()) raise err diff --git a/libs/rss/convert_post_to_text.py b/libs/rss/convert_post_to_text.py index fab0e5787..e7e9a59ab 100644 --- a/libs/rss/convert_post_to_text.py +++ b/libs/rss/convert_post_to_text.py @@ -1,8 +1,9 @@ import logging from typing import Optional + from bs4 import BeautifulSoup -log = logging.getLogger("runner") +log = logging.getLogger("bot.rss") async def get_text_from_entry(entry: dict) -> Optional[str]: "Get the text from an RSS feed entry" @@ -10,7 +11,7 @@ async def get_text_from_entry(entry: dict) -> Optional[str]: return await convert_post_to_text(entry["content"][0]["value"], entry["content"][0]["type"]) if "summary" in entry: return await convert_post_to_text(entry["summary"], entry["summary_detail"]["type"]) - log.error("[rss] No content or summary in entry for article %s", entry['link']) + log.error("No content or summary in entry for article %s", entry['link']) return None async def convert_post_to_text(post: str, post_type: str) -> Optional[str]: @@ -20,7 +21,7 @@ async def convert_post_to_text(post: str, post_type: str) -> Optional[str]: elif post_type == "text/plain": return post else: - log.error("[rss] Unknown post type: %s", post_type) + log.error("Unknown post type: %s", post_type) return None diff --git a/libs/serverconfig/converters.py b/libs/serverconfig/converters.py index f21db33de..a2ada5e3e 100644 --- a/libs/serverconfig/converters.py +++ b/libs/serverconfig/converters.py @@ -12,7 +12,7 @@ from libs.getch_methods import getch_channel_or_thread from libs.serverconfig.options_list import options as options_list -log = logging.getLogger("runner") +log = logging.getLogger("bot") UnicodeEmojis = EmojisManager(None).unicode_set class IntOptionRepresentation(TypedDict): diff --git a/start.py b/start.py index 92e0c2df3..acdf99013 100644 --- a/start.py +++ b/start.py @@ -29,16 +29,15 @@ def check_libs(): from random import choice from fcts import tokens # pylint: disable=no-name-in-module from libs.bot_classes import Axobot -from libs.boot_utils import set_beta_logs, setup_start_parser, setup_bot_logger, setup_database_logger, load_cogs, load_sql_connection +from libs.boot_utils import set_beta_logs, setup_start_parser, setup_logger, load_cogs, load_sql_connection async def main(): "Load everything and start the bot" parser = setup_start_parser() args = parser.parse_args() - log = setup_bot_logger() + log = setup_logger() log.info("Starting bot") - setup_database_logger() client = Axobot(case_insensitive=True, status=discord.Status('online'))