Issue #1091 resolved

log.screen = False has no effect in Python 3.2 when no log files are specified

Anonymous created an issue

== Problem ==

Due to a change in Python 3.2, log.screen has no effect when the relevant log file is not set. Log messages are emitted to the screen even when log.screen is False.

Python 3.2 added a "last resort" handler to the Logger object. Logger.lastResort is an object whose .stream() method returns the current value of sys.stderr, and it is called if no handlers are attached to the logger. When log.screen is set to False and the access or error file is not specified, the Logger has no handlers. In this case the lastResort handler is called and messages are printed to sys.stderr.

== How to reproduce ==

This can be reproduced with a very simple CherryPy app:

{{{ import cherrypy

class TestApp: @cherrypy.expose() def index(self): return "Hello world!"

if name == 'main': cherrypy.config.update({'log.screen': False}) cherrypy.quickstart(TestApp()) }}}

== Solutions ==

The docs offer two solutions:

From http://docs.python.org/py3k/howto/logging.html#what-happens-if-no-configuration-is-provided: {{{ To obtain the pre-3.2 behaviour, logging.lastResort can be set to None. }}}

Another possible solution is to add a logging.NullHandler to error_log and access_log. The NullHandler defines empty handler methods, so does nothing but prevent lastResort from being called.

http://docs.python.org/py3k/howto/logging.html#configuring-logging-for-a-library

I'm not sure which is the better approach.

== Links ==

Discussion of this change can be found here: http://mail.python.org/pipermail/python-dev/2010-December/106556.html

The patch adding the last resort handler: http://hg.python.org/cpython/rev/c86dc2bd3ae8

Another relevant Python bug (this patch should make the problem go away for access messages): http://bugs.python.org/issue12637

Reported by alex@hill.net.au

Comments (3)

  1. Anonymous

    The patch adds NullHandlers to the two loggers.

    I thought this was the best way to go because stdlib logging would actually have been emitting warnings if not for the lines overriding it at the top of _cplogging.py.

    Because logging.NullHandler is so simple and unlikely to change, I just redefined it - that way we don't have to worry about older Pythons.

  2. Log in to comment