1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-05-30 07:09:39 +03:00

Documentation update and getLogger() -> get_logger()

* Technically %(class)s can be e.g. A.B not just 'B' so say "name(s)".
* To not confuse EDMCLogging.getLogger() with logging.getLogger() it's
 been renamed to get_logger().
* Note how we signal errors with finding class and/or qualname.
* Call out EDMCLogging.py in Contributing.md.
This commit is contained in:
Athanasius 2020-07-25 16:14:57 +01:00
parent 2eba647f17
commit 66e2c354c7
3 changed files with 24 additions and 17 deletions

View File

@ -246,11 +246,13 @@ No:
We have implemented a `logging.Filter` that adds support for the following We have implemented a `logging.Filter` that adds support for the following
in `logging.Formatter()` strings: in `logging.Formatter()` strings:
1. `%(qualname)s` which gets the full `ClassA(.ClassB...).func` of the 1. `%(qualname)s` which gets the full `<module>.ClassA(.ClassB...).func`
calling function.
1. `%(class)s` which gets just the immediately encloding class name
of the calling function. of the calling function.
1. `%(class)s` which gets just the enclosing class name(s) of the calling
function.
If you want to see how we did this, check `EDMCLogging.py`.
So don't worry about adding anything about the class or function you're So don't worry about adding anything about the class or function you're
logging from, it's taken care of. logging from, it's taken care of.

View File

@ -44,7 +44,7 @@ class logger(object):
self.logger_channel.setFormatter(self.logger_formatter) self.logger_channel.setFormatter(self.logger_formatter)
self.logger.addHandler(self.logger_channel) self.logger.addHandler(self.logger_channel)
def getLogger(self) -> logging.Logger: def get_logger(self) -> logging.Logger:
""" """
:return: The logging.Logger instance. :return: The logging.Logger instance.
""" """
@ -60,12 +60,18 @@ class EDMCContextFilter(logging.Filter):
""" """
Attempt to set the following in the LogRecord: Attempt to set the following in the LogRecord:
1. class = class name of the call site, if applicable 1. class = class name(s) of the call site, if applicable
2. qualname = __qualname__ of the call site. This simplifies 2. qualname = __qualname__ of the call site. This simplifies
logging.Formatter() as you can use just this no matter if there is logging.Formatter() as you can use just this no matter if there is
a class involved or not, so you get a nice clean: a class involved or not, so you get a nice clean:
<file/module>.<classA>[.classB....].<function> <file/module>.<classA>[.classB....].<function>
If we fail to be able to properly set either then:
1. Use print() to alert, to be SURE a message is seen.
2. But also return strings noting the error, so there'll be
something in the log output if it happens.
:param record: The LogRecord we're "filtering" :param record: The LogRecord we're "filtering"
:return: bool - Always true in order for this record to be logged. :return: bool - Always true in order for this record to be logged.
""" """
@ -86,11 +92,11 @@ class EDMCContextFilter(logging.Filter):
def caller_class_and_qualname(self) -> Tuple[str, str]: def caller_class_and_qualname(self) -> Tuple[str, str]:
""" """
Figure out our caller's class name and qualname Figure out our caller's class name(s) and qualname
Ref: <https://gist.github.com/techtonik/2151726#gistcomment-2333747> Ref: <https://gist.github.com/techtonik/2151726#gistcomment-2333747>
:return: Tuple[str, str]: The caller's class name and qualname :return: Tuple[str, str]: The caller's class name(s) and qualname
""" """
# 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
@ -110,10 +116,9 @@ class EDMCContextFilter(logging.Filter):
break # We've found the frame we want break # We've found the frame we want
frame = frame.f_back frame = frame.f_back
caller_qualname = caller_class_name = '' caller_qualname = caller_class_names = ''
if frame: if frame:
if frame.f_locals and 'self' in frame.f_locals: if frame.f_locals and 'self' in frame.f_locals:
# Find __qualname__ of the caller # Find __qualname__ of the caller
# Paranoia checks # Paranoia checks
if frame.f_code and frame.f_code.co_name: if frame.f_code and frame.f_code.co_name:
@ -122,18 +127,18 @@ class EDMCContextFilter(logging.Filter):
if fn and fn.__qualname__: if fn and fn.__qualname__:
caller_qualname = fn.__qualname__ caller_qualname = fn.__qualname__
# Find immediate containing class name of caller, if any # Find containing class name(s) of caller, if any
frame_class = frame.f_locals['self'].__class__ frame_class = frame.f_locals['self'].__class__
# Paranoia checks # Paranoia checks
if frame_class and frame_class.__qualname__: if frame_class and frame_class.__qualname__:
caller_class_name = frame_class.__qualname__ caller_class_names = frame_class.__qualname__
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()>' caller_qualname = '<ERROR in EDMCLogging.caller_class_and_qualname() for "qualname">'
if caller_class_name == '': if caller_class_names == '':
print('ALERT! Something went wrong with finding caller class name for logging!') print('ALERT! Something went wrong with finding caller class name(s) for logging!')
caller_class_name = '<ERROR in EDMCLogging.caller_class_and_qualname()>' caller_class_names = '<ERROR in EDMCLogging.caller_class_and_qualname() for "class">'
return (caller_class_name, caller_qualname) return (caller_class_names, caller_qualname)

View File

@ -954,7 +954,7 @@ if __name__ == "__main__":
import tempfile import tempfile
sys.stdout = sys.stderr = open(join(tempfile.gettempdir(), '%s.log' % appname), 'wt', 1) # unbuffered not allowed for text in python3, so use line buffering sys.stdout = sys.stderr = open(join(tempfile.gettempdir(), '%s.log' % appname), 'wt', 1) # unbuffered not allowed for text in python3, so use line buffering
logger = EDMCLogging.logger(appname).getLogger() logger = EDMCLogging.logger(appname).get_logger()
# Plain, not via `logger` # Plain, not via `logger`
print(f'{applongname} {appversion}') print(f'{applongname} {appversion}')