[Tutor] Extending logging module

jay titleistfour at gmail.com
Thu Aug 9 21:05:09 CEST 2007


I have a working solution for this, based largely on what Kent posted.
Thought I would post it for others in case your either curious, or need to
do this in the future.  There are probably other ways to do this.

To add a new level NOTICE for logging to syslog

    # Change the default levels to include NOTICE in
    # the proper order of priority
    logging.FATAL = logging.CRITICAL = 60
    logging.ERROR = 50
    logging.WARN = logging.WARNING = 40
    logging.NOTICE = 30

    # insert the levels with all the redefined values
    # anything below NOTICE we don't have to add back in, its
    # not getting redefined above with a new value
    logging.addLevelName(logging.NOTICE, 'NOTICE')
    logging.addLevelName(logging.WARNING, 'WARNING')
    logging.addLevelName(logging.WARN, 'WARN')
    logging.addLevelName(logging.ERROR, 'ERROR')
    logging.addLevelName(logging.FATAL, 'FATAL')
    logging.addLevelName(logging.CRITICAL, 'CRITICAL')

    # define a new logger function for notice
    # this is exactly like existing info, critical, debug...etc
    def Logger_notice(self, msg, *args, **kwargs):
        """
        Log 'msg % args' with severity 'NOTICE'.

        To pass exception information, use the keyword argument exc_info
with
        a true value, e.g.

        logger.notice("Houston, we have a %s", "major disaster", exc_info=1)
        """
        if self.manager.disable >= logging.NOTICE:
            return
        if logging.NOTICE >= self.getEffectiveLevel():
            apply(self._log, (logging.NOTICE, msg, args), kwargs)

    # make the notice function known in the system Logger class
    logging.Logger.notice = Logger_notice

    # define a new root level notice function
    # this is exactly like existing info, critical, debug...etc
    def root_notice(msg, *args, **kwargs):
        """
        Log a message with severity 'NOTICE' on the root logger.
        """
        if len(root.handlers) == 0:
            basicConfig()
        apply(root.notice, (msg,)+args, kwargs)

    # make the notice root level function known
    logging.notice = root_notice

    # add NOTICE to the priority map of all the levels
    logging.handlers.SysLogHandler.priority_map['NOTICE'] = 'notice'


>From there you can create your new logger and do a myLog.notice('test notice
message').  It works quite nicely, though its a lot of repeated code if you
have to define several new levels.

Thanks for your suggestion Kent.  Will wait and see if I get a different
response from comp.lang.python.

Jay



On 8/9/07, jay <titleistfour at gmail.com> wrote:
>
> Kent,
>
> Thanks for the suggestion.  If will look more into your suggestions, and
> also shoot a post over to comp.lang.python.
>
> Jay
>
> On 8/9/07, Kent Johnson <kent37 at tds.net> wrote:
> >
> > jay wrote:
> > > Hello,
> > >
> > > I've been using the python logging module a lot lately, and I've come
> > > across an instance where I need some new levels.  Specifically, python
> > > does not include ALERT and NOTICE in the default set of logging
> > levels.
> > > I am wondering how trivial it would be to extend the logging module to
> >
> > > include these 2 levels that are standard with syslog?
> > >
> > > My first test was just to use the addLevelName method to add the two
> > new
> > > levels, but syslog ignores them and logs at the next highest priority,
> >
> > > no matter what I use.
> > >
> > > Looking further into the code and as a test, I changed the following
> > to
> > > see if this would even work
> > >
> > > lib/python2.5/logging/__init__.py
> > >   -> class Logger
> > >   -> add new notice and alert root level functions
> > >   -> new _levelNames for notice and alert
> > >   -> new default level names for notice and alert
> >
> > You could do all this by patching the logging module at runtime:
> > import logging
> > logging.ALERT = 60
> > logging.addLevelName(logging.ALERT, 'ALERT')
> >
> > def Logger_alert(self, msg, *args, **kwargs):
> >   ...
> >
> > logging.Logger.alert = Logger_alert
> >
> > def alert(msg, *args, **kwargs):
> >    ...
> >
> > logging.alert = alert
> >
> > It's a little ugly but since you are just extending the module with new
> > constants and functions it seems pretty safe and clean to me. It would
> > be cool if addLevelName() did all this patching for you, it wouldn't be
> > hard to do...maybe you want to propose a patch...
> >
> > > lib/python2.5/logging/handlers.py
> > >   -> class SysLogHandler priority_map was changed to include notice
> > and
> > > alert
> >
> > You can do this by subclassing SysLogHandler:
> >
> > class FixedSysLogHandler(SysLogHandler):
> >    priority_map = { ... }
> >
> > then configure logging to use FixedSysLogHandler instead of
> > SysLogHandler.
> >
> >
> > You might want to post about this on comp.lang.python , I think the
> > author of the logging module will see it there.
> >
> > Kent
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/tutor/attachments/20070809/35e2244d/attachment.html 


More information about the Tutor mailing list