Skip to content

Commit

Permalink
feat(logs): better format and loggers hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
ZRunner committed Jan 6, 2024
1 parent 82e1794 commit 7471a56
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 35 deletions.
5 changes: 2 additions & 3 deletions libs/boot_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -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"
]
48 changes: 30 additions & 18 deletions libs/boot_utils/logs_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion libs/bot_classes/axobot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 8 additions & 6 deletions libs/database.py
Original file line number Diff line number Diff line change
@@ -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']):
Expand All @@ -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):
Expand Down Expand Up @@ -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

Expand Down
7 changes: 4 additions & 3 deletions libs/rss/convert_post_to_text.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
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"
if "content" in entry:
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]:
Expand All @@ -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


Expand Down
2 changes: 1 addition & 1 deletion libs/serverconfig/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
5 changes: 2 additions & 3 deletions start.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'))

Expand Down

0 comments on commit 7471a56

Please sign in to comment.