Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #866 (closed enhancement: fixed)

Opened 11 years ago

Last modified 10 years ago

[PATCH] config.py logging enhancement

Reported by: rune.hansen@… Owned by: anonymous
Priority: normal Milestone: 1.0b1
Component: TurboGears Version: 0.9a6
Severity: normal Keywords: logging
Cc:

Description

This enhancement will expose all loggers contained in the logging package. The motivation was to expose RotatingFileHandler and TimedRotatingFileHandler.

I'm not convinced that the implicit tupple structure of args is ideal, it seems prone to errors. On the other hand, I've got no better suggestion at the moment.

import logging
import logging.handlers

def _get_handlers(handlers, formatters):
    for key, handler in handlers.items():
        kw = {}
        try:
            cls = handler.get("class")
            args = handler.get("args", tuple())
            level = handler.get("level", None)
            try:
                cls = getattr(sys.modules['logging'],cls)
            except AttributeError:
                try:
                    cls = getattr(sys.modules['logging.handlers'],cls)
                except AttributeError,err:
                    raise ConfigError("Specified class in handler %s is not a recognizable logger name" % key)
            try:
                handler_obj = cls(*eval(args))
            except IOError,err:
                raise ConfigError("Missing or wrong argument to %s in handler %s -> %s "%(cls.__name__,key,err))
            except TypeError,err:
                raise ConfigError("Wrong format for arguments to %s in handler %s -> %s"%(cls.__name__,key,err))
            if level:
                level = eval(level, logging.__dict__)
                handler_obj.setLevel(level)                
        except KeyError:
            raise ConfigError("No class specified for logging handler %s" % key)
        formatter = handler.get("formatter", None)
        if formatter:
            try:
                formatter = formatters[formatter]
            except KeyError:
                raise ConfigError("Handler %s references unknown "
                            "formatter %s" % (key, formatter))
            handler_obj.setFormatter(formatter)
        handlers[key] = handler_obj

Change History

comment:1 Changed 11 years ago by rune.hansen@…

#866 resolves #820

comment:2 Changed 11 years ago by michele

  • Summary changed from config.py logging enhancement to [PATCH] config.py logging enhancement

comment:3 Changed 11 years ago by kevin

  • Status changed from new to closed
  • Resolution set to fixed

Committed in [1479]. Thanks!

comment:4 Changed 11 years ago by kevin

I should note, that I changed the getattrs(sys.modules) to eval, to be consistent with the logging module docs. I've also changed it to eval args in the logging module context.

comment:5 Changed 11 years ago by rune.hansen@…

I'm not too sure about the use of eval(). Sometimes it can't be helped - one have to use eval() but most times getattr is better: Eval is Evil,  http://diveintomark.org/archives/2002/01/04/eval_is_evil

Mark also comments that [...]getattr() is also much faster,[...]. Now, I won't let my views about the logging package be publicly know. It's in stdlib and we're stuck with it.

Anyway, the handler_obj = cls(*eval(args, logging.__dict__)) doesn't do anything useful with logging.dict.

comment:6 Changed 11 years ago by kevin

well, sure, eval is evil if you're letting Joe Random Person On The Web send you code that you eval. If someone's got access to your server config files, it's too late already.

The reason for eval'ing in the logging namespace is just for consistency with the logging module documentation. That way someone knows what to expect to be available (like sys.stdout, for example).

I am open to better logging implementations, but it would have to be quite visibly better (and easy_installable).

Note: See TracTickets for help on using tickets.