Skip to content

Instantly share code, notes, and snippets.

@justinvh
Last active December 15, 2015 04:38
Show Gist options
  • Save justinvh/5202594 to your computer and use it in GitHub Desktop.
Save justinvh/5202594 to your computer and use it in GitHub Desktop.
This gist demonstrates how to augment a logging record. In the example below we use it to change how a context manager logs. This is a Python 3+ solution, but can be converted to 2.7 fairly easily.
import logging
import inspect
import sys
import time
import contextlib
class AugmentedLogger(logging.getLoggerClass()):
"""A simple augmented logger that allows you to specify an arbitrary
stack-depth when logging relative to the caller function.
"""
def _log(self, l, msg, args, exc=None, extra=None, stack=False, depth=0):
# We look-up down the stack to the caller function and pull the
# necessary meta-data for this call. This is not guaranteed to work
# for all types of Python--consult the actual logging module for some
# insight into how they handle this for IronPython.
stack = inspect.stack()
assert len(stack) > 2 + depth
frame, filename, lineno, function, *other = stack[2 + depth]
rec_args = (self.name, l, filename, lineno, msg,
args, exc, function, extra, inspect.trace())
record = self.makeRecord(*rec_args)
self.handle(record)
logging.setLoggerClass(AugmentedLogger)
logging.basicConfig(format='%(funcName)s:%(lineno)s %(message)s')
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
@contextlib.contextmanager
def timer(name):
t1 = time.time()
yield
total_time = time.time() - t1
# The depth is set to 2 since we are technically in the __exit__ and we
# want to go up through exit and to the parent function.
logger.debug('{}: {}ms'.format(name, total_time), depth=2)
def sum_n(n):
with timer('summing range'):
logger.info('total: {}'.format(sum(range(n))))
if __name__ == '__main__':
n = int(sys.argv[1]) if len(sys.argv) > 1 else 10000
sum_n(n)
$ python context.py 100000
sum_n:45 total: 4999950000
sum_n:45 summing range: 0.011365175247192383ms
$ python context.py 100000
sum_n:45 total: 4999950000
timer:40 summing range: 0.012394905090332031ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment