Last active
December 15, 2015 04:38
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ python context.py 100000 | |
sum_n:45 total: 4999950000 | |
sum_n:45 summing range: 0.011365175247192383ms |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ 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