Skip to content

Commit c5a7223

Browse files
committed
setup logging
1 parent 11aa8cd commit c5a7223

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

maya_stubgen/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from ._logging import init_logger
2+
3+
init_logger()

maya_stubgen/_logging.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import datetime
2+
import logging
3+
4+
5+
class CustomFormatter(logging.Formatter):
6+
"""Logging colored formatter, adapted from https://stackoverflow.com/a/56944256/3638629"""
7+
8+
grey = "\x1b[38;21m"
9+
blue = "\x1b[38;5;39m"
10+
yellow = "\x1b[38;5;226m"
11+
green = "\x1b[32m"
12+
red = "\x1b[38;5;196m"
13+
bold_red = "\x1b[31;1m"
14+
reset = "\x1b[0m"
15+
16+
def __init__(self, fmt):
17+
super().__init__()
18+
self.fmt = fmt
19+
self.FORMATS = {
20+
logging.DEBUG: self.grey + self.fmt + self.reset,
21+
logging.INFO: self.blue + self.fmt + self.reset,
22+
logging.SUCCESS: self.green + self.fmt + self.reset,
23+
logging.WARNING: self.yellow + self.fmt + self.reset,
24+
logging.ERROR: self.red + self.fmt + self.reset,
25+
logging.CRITICAL: self.bold_red + self.fmt + self.reset,
26+
}
27+
28+
def format(self, record):
29+
log_fmt = self.FORMATS.get(record.levelno)
30+
formatter = logging.Formatter(log_fmt)
31+
return formatter.format(record)
32+
33+
34+
def add_logging_level(levelName, levelNum, methodName=None):
35+
"""
36+
Comprehensively adds a new logging level to the `logging` module and the
37+
currently configured logging class.
38+
39+
`levelName` becomes an attribute of the `logging` module with the value
40+
`levelNum`. `methodName` becomes a convenience method for both `logging`
41+
itself and the class returned by `logging.getLoggerClass()` (usually just
42+
`logging.Logger`). If `methodName` is not specified, `levelName.lower()` is
43+
used.
44+
45+
To avoid accidental clobberings of existing attributes, this method will
46+
raise an `AttributeError` if the level name is already an attribute of the
47+
`logging` module or if the method name is already present
48+
49+
Example
50+
-------
51+
>>> addLoggingLevel('TRACE', logging.DEBUG - 5)
52+
>>> logging.getLogger(__name__).setLevel("TRACE")
53+
>>> logging.getLogger(__name__).trace('that worked')
54+
>>> logging.trace('so did this')
55+
>>> logging.TRACE
56+
5
57+
58+
"""
59+
if not methodName:
60+
methodName = levelName.lower()
61+
62+
if hasattr(logging, levelName):
63+
raise AttributeError("{} already defined in logging module".format(levelName))
64+
if hasattr(logging, methodName):
65+
raise AttributeError("{} already defined in logging module".format(methodName))
66+
if hasattr(logging.getLoggerClass(), methodName):
67+
raise AttributeError("{} already defined in logger class".format(methodName))
68+
69+
# This method was inspired by the answers to Stack Overflow post
70+
# http://stackoverflow.com/q/2183233/2988730, especially
71+
# http://stackoverflow.com/a/13638084/2988730
72+
def logForLevel(self, message, *args, **kwargs):
73+
if self.isEnabledFor(levelNum):
74+
self._log(levelNum, message, args, **kwargs)
75+
76+
def logToRoot(message, *args, **kwargs):
77+
logging.log(levelNum, message, *args, **kwargs)
78+
79+
logging.addLevelName(levelNum, levelName)
80+
setattr(logging, levelName, levelNum)
81+
setattr(logging.getLoggerClass(), methodName, logForLevel)
82+
setattr(logging, methodName, logToRoot)
83+
84+
85+
def init_logger():
86+
add_logging_level("SUCCESS", logging.INFO + 5)
87+
88+
# Create custom logger logging all five levels
89+
root_logger = logging.getLogger()
90+
root_logger.setLevel(logging.DEBUG)
91+
92+
# Define format for logs
93+
stdout_fmt = "%(levelname)8s | %(message)s"
94+
file_fmt = "%(asctime)s | %(levelname)8s | %(message)s"
95+
96+
# Create stdout handler for logging to the console (logs all five levels)
97+
stdout_handler = logging.StreamHandler()
98+
stdout_handler.setLevel(logging.DEBUG)
99+
stdout_handler.setFormatter(CustomFormatter(stdout_fmt))
100+
101+
# Create file handler for logging to a file (logs all five levels)
102+
today = datetime.date.today()
103+
file_handler = logging.FileHandler(
104+
"my_app_{}.log".format(today.strftime("%Y_%m_%d"))
105+
)
106+
file_handler.setLevel(logging.DEBUG)
107+
file_handler.setFormatter(logging.Formatter(file_fmt))
108+
109+
# Add both handlers to the logger
110+
root_logger.addHandler(stdout_handler)
111+
root_logger.addHandler(file_handler)

0 commit comments

Comments
 (0)