Created
August 27, 2019 17:41
-
-
Save brydavis/82d8b2fdfba0927483b702c4218257da to your computer and use it in GitHub Desktop.
Set logging levels for every function using a "decontextor" (decorator + context manager)
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 argparse | |
import logging, sys | |
# https://docs.python.org/3/howto/logging-cookbook.html | |
logger = logging.getLogger('app') | |
logify_level = logging.ERROR | |
help_statement = """ | |
Accepts integers of corresponding logging levels | |
CRITICAL: 50 | |
ERROR: 40 | |
WARNING: 30 | |
INFO: 20 | |
DEBUG: 10 | |
""" | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
'--level_some', | |
type=int, | |
default=logging.ERROR, | |
help=help_statement) | |
args = parser.parse_args() | |
class logify: | |
def __init__(self, logger, level=None, handler=None, close=True): | |
self.logger = logger | |
self.level = level | |
self.handler = handler | |
self.close = close | |
def __enter__(self): | |
if self.level is not None: | |
self.old_level = self.logger.level | |
self.logger.setLevel(self.level) | |
if self.handler: | |
self.logger.addHandler(self.handler) | |
def __exit__(self, et, ev, tb): | |
if self.level is not None: | |
self.logger.setLevel(self.old_level) | |
if self.handler: | |
self.logger.removeHandler(self.handler) | |
if self.handler and self.close: | |
self.handler.close() | |
# implicit return of None => don't swallow exceptions | |
def __call__(self, func): | |
def wrapper(*args, **kwds): | |
with self: | |
return func(*args, **kwds) | |
return wrapper | |
@logify(logger, level=args.level_some) | |
def some_func(): | |
logger.debug("some func DEBUG") | |
logger.info("some func INFO") | |
logger.warning("some func WARNING") | |
logger.error("some func ERROR") | |
logger.critical("some func CRITICAL") | |
if __name__ == '__main__': | |
logger.addHandler(logging.StreamHandler()) # defaults to stderr | |
logger.setLevel(logging.INFO) | |
logger.info('1. This should appear just once on stderr.') | |
logger.debug('2. This should not appear.') | |
with logify(logger, level=logging.DEBUG): | |
logger.debug('3. This should appear once on stderr.') | |
logger.debug('4. This should not appear.') | |
some_func() | |
h = logging.StreamHandler(sys.stdout) | |
with logify(logger, level=logging.DEBUG, handler=h, close=True): | |
logger.debug('5. This should appear twice - once on stderr and once on stdout.') | |
logger.info('6. This should appear just once on stderr.') | |
logger.debug('7. This should not appear.') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For example, if you wanted to set logging for the function
some_func
:python logify.py --level_some 40
Since 40 is the integer representation for the
logging.ERROR
level.