As of Pylons 0.9.6, the default ini files include a basic configuration for Python's logging module. Its format matches original logging's module file format. Familiarity is good, but the format is too verbose to my taste so I came up with an alternative style to setup logging.
The following function is called at the application start up (e.g. Global ctor):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | def setup_logging(): logfile = config['logfile'] if logfile == 'STDOUT': # special value, used for unit testing logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, #format='%(name)s %(levelname)s %(message)s', #format='%(asctime)s,%(msecs)d %(levelname)s %(message)s', format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%H:%M:%S') else: logdir = os.path.dirname(os.path.abspath(logfile)) if not os.path.exists(logdir): os.makedirs(logdir) logging.basicConfig(filename=logfile, mode='at+', level=logging.DEBUG, format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s', datefmt='%Y-%b-%d %H:%M:%S') setup_thirdparty_logging() |
The setup_thirdparty_logging function searches through the certain keys of the application .ini file which specify logging level for a particular logger (module).
1 2 3 4 5 6 7 8 9 | def setup_thirdparty_logging(): for key in config: if not key.endswith('logging'): continue value = config.get(key) key = key.rstrip('.logging') loglevel = logging.getLevelName(value) log.info('Set %s logging for %s', logging.getLevelName(loglevel), key) logging.getLogger(key).setLevel(loglevel) |
Relevant section of the .ini file (example):
1 2 3 4 5 | sqlalchemy.logging = WARNING sqlalchemy.orm.unitofwork.logging = INFO sqlalchemy.engine.logging = DEBUG sqlalchemy.orm.logging = INFO routes.logging = WARNING |
This means that routes logger (and all sub-loggers such as routes.mapper) only passes through messages of at least WARNING level; sqlalachemy defaults to WARNING level but some loggers are configured with more verbose level to aid debugging.