From 66e2c354c77c4afec22d06f02fd51f3984bb50f6 Mon Sep 17 00:00:00 2001 From: Athanasius Date: Sat, 25 Jul 2020 16:14:57 +0100 Subject: [PATCH] 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. --- Contributing.md | 8 +++++--- EDMCLogging.py | 31 ++++++++++++++++++------------- EDMarketConnector.py | 2 +- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/Contributing.md b/Contributing.md index ef2ab460..dfbd1b1e 100644 --- a/Contributing.md +++ b/Contributing.md @@ -246,11 +246,13 @@ No: We have implemented a `logging.Filter` that adds support for the following in `logging.Formatter()` strings: - 1. `%(qualname)s` which gets the full `ClassA(.ClassB...).func` of the - calling function. - 1. `%(class)s` which gets just the immediately encloding class name + 1. `%(qualname)s` which gets the full `.ClassA(.ClassB...).func` 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 logging from, it's taken care of. diff --git a/EDMCLogging.py b/EDMCLogging.py index 0c7c629d..504467d6 100644 --- a/EDMCLogging.py +++ b/EDMCLogging.py @@ -44,7 +44,7 @@ class logger(object): self.logger_channel.setFormatter(self.logger_formatter) self.logger.addHandler(self.logger_channel) - def getLogger(self) -> logging.Logger: + def get_logger(self) -> logging.Logger: """ :return: The logging.Logger instance. """ @@ -60,12 +60,18 @@ class EDMCContextFilter(logging.Filter): """ 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 logging.Formatter() as you can use just this no matter if there is a class involved or not, so you get a nice clean: .[.classB....]. + 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" :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]: """ - Figure out our caller's class name and qualname + Figure out our caller's class name(s) and qualname Ref: - :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 # 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 frame = frame.f_back - caller_qualname = caller_class_name = '' + caller_qualname = caller_class_names = '' if frame: if frame.f_locals and 'self' in frame.f_locals: - # Find __qualname__ of the caller # Paranoia checks if frame.f_code and frame.f_code.co_name: @@ -122,18 +127,18 @@ class EDMCContextFilter(logging.Filter): if fn and 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__ # Paranoia checks if frame_class and frame_class.__qualname__: - caller_class_name = frame_class.__qualname__ + caller_class_names = frame_class.__qualname__ if caller_qualname == '': print('ALERT! Something went wrong with finding caller qualname for logging!') - caller_qualname = '' + caller_qualname = '' - if caller_class_name == '': - print('ALERT! Something went wrong with finding caller class name for logging!') - caller_class_name = '' + if caller_class_names == '': + print('ALERT! Something went wrong with finding caller class name(s) for logging!') + caller_class_names = '' - return (caller_class_name, caller_qualname) + return (caller_class_names, caller_qualname) diff --git a/EDMarketConnector.py b/EDMarketConnector.py index 4d0e6099..485814a0 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -954,7 +954,7 @@ if __name__ == "__main__": 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 - logger = EDMCLogging.logger(appname).getLogger() + logger = EDMCLogging.logger(appname).get_logger() # Plain, not via `logger` print(f'{applongname} {appversion}')