I was surprised that I didn't find this approach to logging anywhere while reading up on the subject. So, naturally, I think I may be doing something wrong. I set up some simple tests, and this seems to work:
First, the source: log.py
import datetime
import logging
import os
import config
#this is very straightforward, nothing special here.
log = config.Parser('log')
def setup(stream_level=logging.INFO):
"""shared log named {log.name + log.format}.log
call this logging setup method once, in the main function
always refer to the config file when referring to the logger
in modules other than the main file, call a reference to the
already created logger in memory via log.hook(module_name)
as long as this setup() was ran in the main method, the logfile
should already exist in the proper place, with streams created
for use, according to the config file entry for 'log'.
`stream_level` indicates what level of
detail should be printed to the terminal
"""
log.level = log.level.upper()
logger = logging.getLogger(log.name)
logger.setLevel(log.level)
formatter = logging.Formatter(log.format)
formatter.datefmt = log.datefmt
pretty_date = datetime.date.strftime(datetime.datetime.now(), log.datefmt)
date_ext = filter(lambda x: x.isdigit(), pretty_date)
#terminal logging
if stream_level:
ch = logging.StreamHandler()
ch.setLevel(stream_level)
ch.setFormatter(formatter)
#file logging
logname = ''.join([log.name, date_ext, '.log'])
fh = logging.FileHandler(os.path.join(log.dir, logname))
fh.setLevel(log.level)
fh.setFormatter(formatter)
logger.addHandler(fh)
if stream_level:
logger.addHandler(ch)
return logger
def hook(module_name):
"""pass in the special method __name__ for best results
don't call this until you've setup() the logger in your main function
"""
return logging.getLogger('.'.join([log.name, module_name]))
And the main.py
import util
import log
logger = log.setup()
logger.info('starting now')
util.p()
logger.critical('quitting!')
util.py
import log
def p():
logger = log.hook(__name__)
for x in range(10):
logger.warn('.')