You should always use the logging
module instead of just littering print
statements all over your code. You will very quickly thank yourself for taking a bit of extra time.
Having said that, setting up logging is a bit of a pain so here's the pattern I use 90% of the time.
# utils/logging.py
import sys
import logging
class LessThanFilter(logging.Filter):
def __init__(self, max_level, name=""):
super(LessThanFilter, self).__init__(name)
self._max_level = max_level
def filter(self, record):
#non-zero return means we log this message
return record.levelno < self._max_level
class GreaterThanFilter(logging.Filter):
def __init__(self, min_level, name=""):
super(GreaterThanFilter, self).__init__(name)
self._min_level = min_level
def filter(self, record):
#non-zero return means we log this message
return record.levelno >= self._min_level
def create_logger():
logger = logging.getLogger()
logger.setLevel(logging.NOTSET)
h1 = logging.StreamHandler(sys.stdout)
h1.setLevel(logging.INFO)
h1.set_name('stdout')
h1.addFilter( LessThanFilter(h1.level + 1) )
h2 = logging.StreamHandler(sys.stderr)
h2.set_name('stderr')
h2.setLevel(logging.WARNING)
h2.addFilter(GreaterThanFilter(h1.level) )
logger.addHandler(h1)
logger.addHandler(h2)
return logger
logger = create_logger()
and then elsewhere…
from utils.logging import logger
...
logger.info("this will print to stdout")
logger.warn("this will print to stderr")
and from the cmdline you can do the regular unix-like things…
./myutil.py > /dev/null # only see stderr
./myutil.py > /dev/null 2> /tmp/myutil.errors # ignore stdout, write stderr to a file
Remember, applications should configure loggers and libraries never should. Therefore, you must import/create the logger from your main application, and then in your libraries just getLogger
# in a module, at the top of the file
import logging
logger = logging.getLogger('module_name')
logger.debug("a good debug message")