#!/usr/bin/env python
# vim: set encoding=utf-8 et sw=4 sts=4 :
-import logging ; log = logging.getLogger('pymind')
-# First of all, we need to setup the logging framework
-# FIXME: this should go in a configuration file
-logging.basicConfig(
- level = logging.DEBUG,
- format = '%(asctime)s %(name)-24s %(levelname)-8s %(message)s',
- datefmt = '%a, %d %b %Y %H:%M:%S',
-)
+import logging, logging.config ; log = logging.getLogger('pymind')
+# default logging configuration
+# (this is used before the user configuration file gets parsed)
+logging.basicConfig(format='%(levelname)s: %(message)s')
import os
import sys
os.path.expanduser('~/.pymin/pymin.ini'),
]
+# default locations where to look for the log configuration file
+# all found files will be processed, overriding the previous configuration
+# files values.
+log_file_paths = [
+ '/etc/pymin/log.ini',
+ os.path.expanduser('~/.pymin/log.ini'),
+]
+
# default locations where to look for service plug-ins
# search stops when a service plug-in is found
services_paths = [
metavar='SERVICE', help="manage service SERVICE"),
ListOption('services_dirs', V.String, 'd', default=[],
metavar='DIR', help="search for services in DIR"),
+ ListOption('log_config_files', V.String, 'l', default=log_file_paths,
+ metavar='FILE', help="load log configuration FILE"),
ConfigOption('config_file', 'c', metavar='FILE',
help="load the configuration file FILE after the default "
"configuration files"),
log.warning("Can't set ip_forward: %s", e)
+def die(status, msg, *args):
+ log.critical(msg, *args)
+ logging.shutdown()
+ sys.exit(status)
+
def get_config(paths, version, desc, add_options, defaults):
global config_file_paths
try:
(config, args) = load_config(paths, version, desc, add_options, defaults)
except ConfigError, e:
- log.error(str(e))
- sys.exit(EXIT_CONFIG_ERROR)
+ die(EXIT_CONFIG_ERROR, str(e))
except MissingSectionHeaderError, e:
- log.error("%s:%s: missing section header near: %s", e.filename, e.lineno,
- e.line)
- sys.exit(EXIT_CONFIG_ERROR)
+ dir(EXIT_CONFIG_ERROR, "%s:%s: missing section header near: %s",
+ e.filename, e.lineno, e.line)
except ParsingError, e:
for (lineno, line) in e.errors:
- log.error("%s:%s: invalid syntax near: %s", e.filename, lineno, line)
- log.error(str(e.errors))
- sys.exit(EXIT_CONFIG_ERROR)
+ log.critical("%s:%s: invalid syntax near: %s", e.filename, lineno, line)
+ die(EXIT_CONFIG_ERROR, str(e.errors))
except Invalid, e:
- log.error(str(e.unpack_errors()))
- sys.exit(EXIT_CONFIG_ERROR)
+ die(EXIT_CONFIG_ERROR, str(e.unpack_errors()))
except LoadError, e:
- log.error("service '%s' not found (see option --services-dir)",
- e.service_name)
- sys.exit(EXIT_NO_SERVICE)
+ die(EXIT_NO_SERVICE, "service '%s' not found (see option " \
+ "--services-dir)", e.service_name)
return (config, args)
return root
+def setup_logging(config_files):
+ # XXX: this is a hack for re-enabling loggers not configured via
+ # fileConfig(). This function disable all existing loggers that
+ # has no configuration specified in the config file, so we have
+ # to re-enable the by hand.
+ # See Python bug 3136: http://bugs.python.org/issue3136
+ existing = logging.root.manager.loggerDict.keys()
+ loaded_files = 0
+ for f in config_files:
+ try:
+ f = open(f)
+ except Exception, e:
+ log.info("config file '%s' can't be readed (%s)", f, e)
+ continue
+ logging.config.fileConfig(f)
+ f.close()
+ loaded_files += 1
+ if not loaded_files:
+ log.warning('no log config file loaded')
+ # XXX: finish the hack commented above
+ for log in existing:
+ logging.root.manager.loggerDict[log].disabled = 0
+
+
def main():
services = Services()
(config, args) = get_config(config_file_paths, '%prog 0.1',
'Router services administration daemon',
services.add_config_options, config_defaults)
+ setup_logging(config.log_config_files)
root_handler = build_root(config, args, services.services)
activate_ip_forward()
PyminDaemon(root_handler, (config.bind_addr, config.bind_port)).run()
+ logging.shutdown()
if __name__ == '__main__':
main()