← Back to team overview

lazr-developers team mailing list archive

[Bug 310774] Re: Standard way of configuring logging

 

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?

-- 
Standard way of configuring logging
https://bugs.launchpad.net/bugs/310774
You received this bug notification because you are a member of LAZR
Developers, which is the registrant for lazr.config.

Status in lazr.config: Triaged

Bug description:
It's useful to be able to set:
    - log file location
    - severity level cutoff
    - rotation policy
      - how often
      - how are files renamed
      - how many old files are kept

in a configuration file that can be easily edited by sysadmins, rather than in Python code that constructs and assembles logging.Handler objects.



References