Skip to content

Commit 0545ef5

Browse files
committed
Add create_log_handler function. Update imports:
- 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.
1 parent c4fbf0a commit 0545ef5

File tree

2 files changed

+92
-48
lines changed

2 files changed

+92
-48
lines changed

Diff for: bot.py

+8-22
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
11
__version__ = "4.0.1"
22

33

4-
try:
5-
# noinspection PyUnresolvedReferences
6-
from colorama import init
7-
8-
init()
9-
except ImportError:
10-
pass
11-
4+
# early import to initialize colorama
125
from core.models import (
136
DMDisabled,
147
HostingMethod,
158
InvalidConfigError,
169
PermissionLevel,
1710
SafeFormatter,
11+
create_log_handler,
1812
configure_logging,
1913
getLogger,
20-
log_file_formatter,
21-
log_stream_formatter,
2214
)
2315

24-
2516
import asyncio
2617
import copy
2718
import hashlib
@@ -192,8 +183,7 @@ def _configure_logging(self):
192183
logger.info("Logging level: %s", level_text)
193184

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

198188
# Set up discord.py logging
199189
# repeat the step
@@ -202,21 +192,17 @@ def _configure_logging(self):
202192
logger.info("Setting up discord logger, logging level: %s.", logging.getLevelName(log_level))
203193
d_logger = logging.getLogger("discord")
204194
d_logger.setLevel(log_level)
205-
stream = logging.StreamHandler(stream=sys.stdout)
206195
is_debug = not log_level > logging.DEBUG
207-
stream.setLevel(log_level if not is_debug else logging.INFO)
208-
stream.setFormatter(log_stream_formatter)
196+
stream = create_log_handler(level=log_level if not is_debug else logging.INFO)
209197
d_logger.addHandler(stream)
210-
file_handler = logging.handlers.RotatingFileHandler(self.log_file_name, **handler_params)
211-
file_handler.setFormatter(log_file_formatter)
212-
file_handler.setLevel(log_level if not is_debug else logging.INFO)
198+
file_handler = create_log_handler(
199+
self.log_file_name, rotating=True, level=log_level if not is_debug else logging.INFO
200+
)
213201
d_logger.addHandler(file_handler)
214202

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

Diff for: core/models.py

+84-26
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
import re
44
import sys
55

6+
from logging import FileHandler, StreamHandler
67
from logging.handlers import RotatingFileHandler
8+
from typing import Optional, Union
9+
710

811
try:
9-
from colorama import Fore, Style
12+
from colorama import Fore, Style, init as color_init
1013
except ImportError:
1114
Fore = Style = type("Dummy", (object,), {"__getattr__": lambda self, item: ""})()
15+
else:
16+
color_init()
1217

1318

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

6671

67-
logging.setLoggerClass(ModmailLogger)
68-
log_level = logging.INFO
69-
loggers = set()
72+
class FileFormatter(logging.Formatter):
73+
ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")
74+
75+
def format(self, record):
76+
record.msg = self.ansi_escape.sub("", record.msg)
77+
return super().format(record)
78+
7079

71-
ch = logging.StreamHandler(stream=sys.stdout)
72-
ch.setLevel(log_level)
7380
log_stream_formatter = logging.Formatter(
7481
"%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s", datefmt="%m/%d/%y %H:%M:%S"
7582
)
76-
ch.setFormatter(log_stream_formatter)
83+
log_file_formatter = FileFormatter(
84+
"%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s",
85+
datefmt="%Y-%m-%d %H:%M:%S",
86+
)
87+
88+
89+
def create_log_handler(
90+
filename: Optional[str] = None,
91+
*,
92+
rotating: bool = False,
93+
level: int = logging.DEBUG,
94+
mode: str = "a+",
95+
encoding: str = "utf-8",
96+
maxBytes: int = 48000,
97+
backupCount: int = 1,
98+
**kwargs,
99+
) -> Union[FileHandler, RotatingFileHandler, StreamHandler]:
100+
"""
101+
Return a pre-configured log handler. This function is made for consistency sake with
102+
pre-defined default values for parameters and formatters to pass to handler class.
103+
Additional keyword arguments also can be specified, just in case.
104+
105+
Plugin developers should not use this and only use the `getLogger` instead to instantiate the ModmailLogger object.
106+
107+
Parameters
108+
-----------
109+
filename : Optional[Path]
110+
Specifies that a `FileHandler` or `RotatingFileHandler` be created, using the specified filename,
111+
rather than a `StreamHandler`. Defaults to `None`.
112+
rotating : bool
113+
Whether the file handler should be the `RotatingFileHandler`. Defaults to `False`. Note, this
114+
argument only compatible if the `filename` is specified, otherwise `ValueError` will be raised.
115+
level : int
116+
The root logger level for the handler. Defaults to `logging.DEBUG`.
117+
mode : str
118+
If filename is specified, open the file in this mode. Defaults to 'a+'.
119+
encoding : str
120+
If this keyword argument is specified along with filename, its value is used when the `FileHandler` is created,
121+
and thus used when opening the output file. Defaults to 'utf-8'.
122+
maxBytes : int
123+
The max file size before the rollover occurs. Defaults to 48000. Rollover occurs whenever the current log file
124+
is nearly `maxBytes` in length; but if either of `maxBytes` or `backupCount` is zero, rollover never occurs, so you
125+
generally want to set `backupCount` to at least 1.
126+
backupCount : int
127+
Max number of backup files. Defaults to 1. If this is set to zero, rollover will never occur.
128+
"""
129+
if filename is None and rotating:
130+
raise ValueError("`filename` must be set to instantiate a `RotatingFileHandler`.")
131+
132+
if filename is None:
133+
handler = StreamHandler(stream=sys.stdout, **kwargs)
134+
handler.setFormatter(log_stream_formatter)
135+
elif not rotating:
136+
handler = FileHandler(filename, mode=mode, encoding=encoding, **kwargs)
137+
handler.setFormatter(log_file_formatter)
138+
else:
139+
handler = RotatingFileHandler(
140+
filename, mode=mode, encoding=encoding, maxBytes=maxBytes, backupCount=backupCount, **kwargs
141+
)
142+
handler.setFormatter(log_file_formatter)
77143

78-
ch_debug = None
144+
handler.setLevel(level)
145+
return handler
146+
147+
148+
logging.setLoggerClass(ModmailLogger)
149+
log_level = logging.INFO
150+
loggers = set()
151+
ch: StreamHandler = create_log_handler(level=log_level)
152+
ch_debug: Optional[RotatingFileHandler] = None
79153

80154

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

90164

91-
class FileFormatter(logging.Formatter):
92-
ansi_escape = re.compile(r"\x1B\[[0-?]*[ -/]*[@-~]")
93-
94-
def format(self, record):
95-
record.msg = self.ansi_escape.sub("", record.msg)
96-
return super().format(record)
97-
98-
99-
log_file_formatter = FileFormatter(
100-
"%(asctime)s %(name)s[%(lineno)d] - %(levelname)s: %(message)s",
101-
datefmt="%Y-%m-%d %H:%M:%S",
102-
)
103-
104-
105-
def configure_logging(name, level=None, **handler_params):
165+
def configure_logging(name, level: Optional[int] = None):
106166
global ch_debug, log_level
107-
ch_debug = RotatingFileHandler(name, **handler_params)
108-
ch_debug.setFormatter(log_file_formatter)
109-
ch_debug.setLevel(logging.DEBUG)
167+
ch_debug = create_log_handler(name, rotating=True)
110168

111169
if level is not None:
112170
log_level = level

0 commit comments

Comments
 (0)