1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-06-01 08:01:22 +03:00

Cleanups and docstrings

* Added/fleshed out docstrings on file, classes and functions.
* No need to use a function for the stack frame getting.
* Check if LogRecord has class or qualname before setting, allowing
 upstream to implement them.
* Use setattr()/getattr() rather than __dict__ fiddling.
* Force an error string into class/qualname if we have issues finding
 them, rather than failing silently to ''.
This commit is contained in:
Athanasius 2020-07-25 15:22:22 +01:00
parent 596527bda2
commit 5a779a3379

View File

@ -1,5 +1,8 @@
""" """
TODO: blurb This module provides for a common logging-powered log facility.
Mostly it implements a logging.Filter() in order to get two extra
members on the logging.LogRecord instance for use in logging.Formatter()
strings.
""" """
import sys import sys
@ -8,8 +11,14 @@ from typing import Tuple
class logger(object): class logger(object):
""" """
TODO: desc
Wrapper class for all logging configuration and code. Wrapper class for all logging configuration and code.
Class instantiation requires the 'logger name' and optional loglevel.
It is intended that this 'logger name' be re-used in all files/modules
that need to log.
Users of this class should then call getLogger() to get the
logging.Logger instance.
""" """
def __init__(self, logger_name: str, loglevel: int=logging.DEBUG): def __init__(self, logger_name: str, loglevel: int=logging.DEBUG):
""" """
@ -36,48 +45,61 @@ class logger(object):
self.logger.addHandler(self.logger_channel) self.logger.addHandler(self.logger_channel)
def getLogger(self) -> logging.Logger: def getLogger(self) -> logging.Logger:
"""
:return: The logging.Logger instance.
"""
return self.logger return self.logger
class EDMCContextFilter(logging.Filter): class EDMCContextFilter(logging.Filter):
""" """
TODO: Update this logging.Filter sub-class to place extra attributes of the calling site
logging.Filter sub-class to place the calling __class__ in the record. into the record.
""" """
def filter(self, record: logging.LogRecord) -> bool: def filter(self, record: logging.LogRecord) -> bool:
""" """
Attempt to set the following in the LogRecord:
:param record: 1. class = class name of the call site, if applicable
:return: bool - True for this record to be logged. 2. qualname = __qualname__ of the call site. This simplifies
logging.Formatter() as you can use just this no matter if there is
a class involved or not, so you get a nice clean:
<file/module>.<classA>[.classB....].<function>
:param record: The LogRecord we're "filtering"
:return: bool - Always true in order for this record to be logged.
""" """
# TODO: Only set these if they're not already, in case upstream class_name = qualname = ''
# adds them. # Don't even call in if both already set.
# TODO: Try setattr(record, 'class', ... if not getattr(record, 'class', None) or not getattr(record, 'qualname', None):
(class_name, qualname) = self.caller_class_and_qualname() (class_name, qualname) = self.caller_class_and_qualname()
record.__dict__['class'] = class_name
record.__dict__['qualname'] = qualname # Only set if not already provided by logging itself
if getattr(record, 'class', None) is None:
setattr(record, 'class', class_name)
# Only set if not already provided by logging itself
if getattr(record, 'qualname', None) is None:
setattr(record, 'qualname', qualname)
return True return True
def caller_class_and_qualname(self, skip=4) -> Tuple[str, str]: def caller_class_and_qualname(self) -> Tuple[str, str]:
""" """
Figure out our caller's qualname Figure out our caller's class name and qualname
Ref: <https://gist.github.com/techtonik/2151726#gistcomment-2333747> Ref: <https://gist.github.com/techtonik/2151726#gistcomment-2333747>
:param skip: How many stack frames above to look. :return: Tuple[str, str]: The caller's class name and qualname
:return: str: The caller's qualname
""" """
import inspect # TODO: we might as well just walk this below.
# Build the stack of frames from here upwards
stack = []
frame = sys._getframe(0)
while frame:
stack.append(frame)
frame = frame.f_back
# TODO: Fold this into caller_class()
def stack_(frame):
framelist = []
while frame:
framelist.append(frame)
frame = frame.f_back
return framelist
stack = stack_(sys._getframe(0))
# Go up through stack frames until we find the first with a # Go up through stack frames until we find the first with a
# type(f_locals.self) of logging.Logger. This should be the start # type(f_locals.self) of logging.Logger. This should be the start
# of the frames internal to logging. # of the frames internal to logging.
@ -117,8 +139,10 @@ class EDMCContextFilter(logging.Filter):
if caller_qualname == '': if caller_qualname == '':
print('ALERT! Something went wrong with finding caller qualname for logging!') print('ALERT! Something went wrong with finding caller qualname for logging!')
caller_qualname = '<ERROR in EDMCLogging.caller_class_and_qualname()>'
if caller_class_name == '': if caller_class_name == '':
print('ALERT! Something went wrong with finding caller class name for logging!') print('ALERT! Something went wrong with finding caller class name for logging!')
caller_class_name = '<ERROR in EDMCLogging.caller_class_and_qualname()>'
return (caller_class_name, caller_qualname) return (caller_class_name, caller_qualname)