Skip to content

Commit

Permalink
Add create_log_handler function. Update imports:
Browse files Browse the repository at this point in the history
- Move `colorama` import to `models.py`.
- Utilize `create_log_handler`. This function is mainly to pre-configure the default values for parameters to pass into the Handler class.
  • Loading branch information
Jerrie-Aries committed Oct 15, 2022
1 parent c4fbf0a commit 0545ef5
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 48 deletions.
30 changes: 8 additions & 22 deletions bot.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,18 @@
__version__ = "4.0.1"


try:
# noinspection PyUnresolvedReferences
from colorama import init

init()
except ImportError:
pass

# early import to initialize colorama
from core.models import (
DMDisabled,
HostingMethod,
InvalidConfigError,
PermissionLevel,
SafeFormatter,
create_log_handler,
configure_logging,
getLogger,
log_file_formatter,
log_stream_formatter,
)


import asyncio
import copy
import hashlib
Expand Down Expand Up @@ -192,8 +183,7 @@ def _configure_logging(self):
logger.info("Logging level: %s", level_text)

logger.info("Log file: %s", self.log_file_name)
handler_params = dict(mode="a+", maxBytes=48000, backupCount=1, encoding="utf-8")
configure_logging(self.log_file_name, log_level, **handler_params)
configure_logging(self.log_file_name, log_level)

# Set up discord.py logging
# repeat the step
Expand All @@ -202,21 +192,17 @@ def _configure_logging(self):
logger.info("Setting up discord logger, logging level: %s.", logging.getLevelName(log_level))
d_logger = logging.getLogger("discord")
d_logger.setLevel(log_level)
stream = logging.StreamHandler(stream=sys.stdout)
is_debug = not log_level > logging.DEBUG
stream.setLevel(log_level if not is_debug else logging.INFO)
stream.setFormatter(log_stream_formatter)
stream = create_log_handler(level=log_level if not is_debug else logging.INFO)
d_logger.addHandler(stream)
file_handler = logging.handlers.RotatingFileHandler(self.log_file_name, **handler_params)
file_handler.setFormatter(log_file_formatter)
file_handler.setLevel(log_level if not is_debug else logging.INFO)
file_handler = create_log_handler(
self.log_file_name, rotating=True, level=log_level if not is_debug else logging.INFO
)
d_logger.addHandler(file_handler)

# internal discord.py debug logging
if is_debug:
debug_handler = logging.FileHandler(filename="discord.log", encoding="utf-8", mode="w")
debug_handler.setLevel(log_level)
debug_handler.setFormatter(log_file_formatter)
debug_handler = create_log_handler("discord.log", level=log_level, mode="w", encoding="utf-8")
logger.info("Discord logger DEBUG level is enabled. Log file: %s", "discord.log")
d_logger.addHandler(debug_handler)

Expand Down
110 changes: 84 additions & 26 deletions core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
import re
import sys

from logging import FileHandler, StreamHandler
from logging.handlers import RotatingFileHandler
from typing import Optional, Union


try:
from colorama import Fore, Style
from colorama import Fore, Style, init as color_init
except ImportError:
Fore = Style = type("Dummy", (object,), {"__getattr__": lambda self, item: ""})()
else:
color_init()


if ".heroku" in os.environ.get("PYTHONHOME", ""):
Expand Down Expand Up @@ -64,18 +69,87 @@ def line(self, level="info"):
)


logging.setLoggerClass(ModmailLogger)
log_level = logging.INFO
loggers = set()
class FileFormatter(logging.Formatter):
ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")

def format(self, record):
record.msg = self.ansi_escape.sub("", record.msg)
return super().format(record)


ch = logging.StreamHandler(stream=sys.stdout)
ch.setLevel(log_level)
log_stream_formatter = logging.Formatter(
"%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%m/%d/%y %H:%M:%S"
)
ch.setFormatter(log_stream_formatter)
log_file_formatter = FileFormatter(
"%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)


def create_log_handler(
filename: Optional[str] = None,
*,
rotating: bool = False,
level: int = logging.DEBUG,
mode: str = "a+",
encoding: str = "utf-8",
maxBytes: int = 48000,
backupCount: int = 1,
**kwargs,
) -> Union[FileHandler, RotatingFileHandler, StreamHandler]:
"""
Return a pre-configured log handler. This function is made for consistency sake with
pre-defined default values for parameters and formatters to pass to handler class.
Additional keyword arguments also can be specified, just in case.
Plugin developers should not use this and only use the `getLogger` instead to instantiate the ModmailLogger object.
Parameters
-----------
filename : Optional[Path]
Specifies that a `FileHandler` or `RotatingFileHandler` be created, using the specified filename,
rather than a `StreamHandler`. Defaults to `None`.
rotating : bool
Whether the file handler should be the `RotatingFileHandler`. Defaults to `False`. Note, this
argument only compatible if the `filename` is specified, otherwise `ValueError` will be raised.
level : int
The root logger level for the handler. Defaults to `logging.DEBUG`.
mode : str
If filename is specified, open the file in this mode. Defaults to 'a+'.
encoding : str
If this keyword argument is specified along with filename, its value is used when the `FileHandler` is created,
and thus used when opening the output file. Defaults to 'utf-8'.
maxBytes : int
The max file size before the rollover occurs. Defaults to 48000. Rollover occurs whenever the current log file
is nearly `maxBytes` in length; but if either of `maxBytes` or `backupCount` is zero, rollover never occurs, so you
generally want to set `backupCount` to at least 1.
backupCount : int
Max number of backup files. Defaults to 1. If this is set to zero, rollover will never occur.
"""
if filename is None and rotating:
raise ValueError("`filename` must be set to instantiate a `RotatingFileHandler`.")

if filename is None:
handler = StreamHandler(stream=sys.stdout, **kwargs)
handler.setFormatter(log_stream_formatter)
elif not rotating:
handler = FileHandler(filename, mode=mode, encoding=encoding, **kwargs)
handler.setFormatter(log_file_formatter)
else:
handler = RotatingFileHandler(
filename, mode=mode, encoding=encoding, maxBytes=maxBytes, backupCount=backupCount, **kwargs
)
handler.setFormatter(log_file_formatter)

ch_debug = None
handler.setLevel(level)
return handler


logging.setLoggerClass(ModmailLogger)
log_level = logging.INFO
loggers = set()
ch: StreamHandler = create_log_handler(level=log_level)
ch_debug: Optional[RotatingFileHandler] = None


def getLogger(name=None) -> ModmailLogger:
Expand All @@ -88,25 +162,9 @@ def getLogger(name=None) -> ModmailLogger:
return logger


class FileFormatter(logging.Formatter):
ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")

def format(self, record):
record.msg = self.ansi_escape.sub("", record.msg)
return super().format(record)


log_file_formatter = FileFormatter(
"%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)


def configure_logging(name, level=None, **handler_params):
def configure_logging(name, level: Optional[int] = None):
global ch_debug, log_level
ch_debug = RotatingFileHandler(name, **handler_params)
ch_debug.setFormatter(log_file_formatter)
ch_debug.setLevel(logging.DEBUG)
ch_debug = create_log_handler(name, rotating=True)

if level is not None:
log_level = level
Expand Down

0 comments on commit 0545ef5

Please sign in to comment.