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.
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:
{{{ basicConfig( format= config. logging. root.format,
datefmt= config. logging. root.datefmt,
level= as_log_ level(config. logging. root.level) ) logger_ configs: config. name.split( '.')[-1] getLogger( logger_ name) config. format config. datefmt
log.propagate = as_boolean( logger_ config. propagate)
log.setLevel( as_log_ level(logger_ config. level)) Formatter( fmt=log_ format, datefmt= log_datefmt) normpath( os.path. join(config. LOG_DIR, path_str)) andler( path_abs)
_handlers. append( handler)
handler. setFormatter( formatter)
log.addHandler (handler)
# First, find the root logger and configure the logging subsystem.
# Initialize the root logger, then create a formatter for all the sublogs.
logging.
# Create the subloggers
for logger_config in config.
logger_name = 'mailman.' + logger_
log = logging.
# Get settings from log configuration file (or defaults).
log_format = logger_
log_datefmt = logger_
# Propagation to the root logger is how we handle logging to stderr
# when the qrunners are not run as a subprocess of mailmanctl.
# Set the logger's level.
# Create a formatter for this logger, then a handler, and link the
# formatter to the handler.
formatter = logging.
path_str = logger_config.path
path_abs = os.path.
handler = ReopenableFileH
}}}
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?