From d2f084304169f8e8e3f06daa9c5aff709b60c236 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Tue, 5 Oct 2021 17:04:11 -0400 Subject: [PATCH] Make custom log levels report the right stack frame The stdlib's `logging.LoggingAdapter` doesn't currently pass through `stacklevel: int` down to its wrapped logger instance. Hack it here and get our msgs looking like they would if using a built-in level. --- tractor/log.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tractor/log.py b/tractor/log.py index 4bfc798..164e76b 100644 --- a/tractor/log.py +++ b/tractor/log.py @@ -2,7 +2,6 @@ Log like a forester! """ import sys -from functools import partial import logging import colorlog # type: ignore from typing import Optional @@ -75,6 +74,42 @@ class StackLevelAdapter(logging.LoggerAdapter): ) -> None: return self.log(500, msg) + def log(self, level, msg, *args, **kwargs): + """ + Delegate a log call to the underlying logger, after adding + contextual information from this adapter instance. + """ + if self.isEnabledFor(level): + # msg, kwargs = self.process(msg, kwargs) + self._log(level, msg, args, **kwargs) + + # LOL, the stdlib doesn't allow passing through ``stacklevel``.. + def _log( + self, + level, + msg, + args, + exc_info=None, + extra=None, + stack_info=False, + + # XXX: bit we added to show fileinfo from actual caller. + # this level then ``.log()`` then finally the caller's level.. + stacklevel=3, + ): + """ + Low-level log implementation, proxied to allow nested logger adapters. + """ + return self.logger._log( + level, + msg, + args, + exc_info=exc_info, + extra=self.extra, + stack_info=stack_info, + stacklevel=stacklevel, + ) + def get_logger(