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.