Jono, let me understand better what you're thinking about. I have some similar code in Mailman, but I'm trying to think about how to generalize this. In my schema.conf file I have the following: {{{ [logging.template] # This defines various log settings. The options available are: # # - level -- Overrides the default level; this may be any of the # standard Python logging levels, case insensitive. # - format -- Overrides the default format string # - datefmt -- Overrides the default date format string # - path -- Overrides the default logger path. This may be a relative # path name, in which case it is relative to Mailman's LOG_DIR, # or it may be an absolute path name. You cannot change the # handler class that will be used. # - propagate -- Boolean specifying whether to propagate log message from this # logger to the root "mailman" logger. You cannot override # settings for the root logger. # # In this section, you can define defaults for all loggers, which will be # prefixed by 'mailman.'. Use subsections to override settings for specific # loggers. The names of the available loggers are: # # - archiver -- All archiver output # - bounce -- All bounce processing logs go here # - config -- Configuration issues # - debug -- Only used for development # - error -- All exceptions go to this log # - fromusenet -- Information related to the Usenet to Mailman gateway # - http -- Internal wsgi-based web interface # - locks -- Lock state changes # - mischief -- Various types of hostile activity # - post -- Information about messages posted to mailing lists # - qrunner -- qrunner start/stops # - smtp -- Successful SMTP activity # - smtp-failure -- Unsuccessful SMTP activity # - subscribe -- Information about leaves/joins # - vette -- Information related to admindb activity format: %(asctime)s (%(process)d) %(message)s datefmt: %b %d %H:%M:%S %Y propagate: no level: info path: mailman [logging.root] [logging.archiver] [logging.bounce] path: bounce [logging.config] [logging.debug] path: debug level: debug [logging.error] [logging.fromusenet] [logging.http] [logging.locks] [logging.mischief] [logging.qrunner] [logging.smtp] path: smtp [logging.subscribe] [logging.vette] }}} then in my logger initialize code, I've got something like this: {{{ # First, find the root logger and configure the logging subsystem. # Initialize the root logger, then create a formatter for all the sublogs. logging.basicConfig(format=config.logging.root.format, datefmt=config.logging.root.datefmt, level=as_log_level(config.logging.root.level)) # Create the subloggers for logger_config in config.logger_configs: logger_name = 'mailman.' + logger_config.name.split('.')[-1] log = logging.getLogger(logger_name) # Get settings from log configuration file (or defaults). log_format = logger_config.format log_datefmt = logger_config.datefmt # Propagation to the root logger is how we handle logging to stderr # when the qrunners are not run as a subprocess of mailmanctl. log.propagate = as_boolean(logger_config.propagate) # Set the logger's level. log.setLevel(as_log_level(logger_config.level)) # Create a formatter for this logger, then a handler, and link the # formatter to the handler. formatter = logging.Formatter(fmt=log_format, datefmt=log_datefmt) path_str = logger_config.path path_abs = os.path.normpath(os.path.join(config.LOG_DIR, path_str)) handler = ReopenableFileHandler(path_abs) _handlers.append(handler) handler.setFormatter(formatter) log.addHandler(handler) }}} The way I'm thinking about generalizing this depends on bug 310619 which allows you to set a .master section that can be extended in the config file. You'd then define the .master section in your schema file like so. {{{ [logging.master] format: %(asctime)s (%(process)d) %(message)s datefmt: %b %d %H:%M:%S %Y propagate: no level: info path: /var/log/log.log formatter: logging.Formatter handler: logging.Handler }}} There are some tricky bits, such as how do you define the arguments to pass to the handler? Anyway, what do you think?