CherryPy静默日志记录在Windows服务上不起作用



环境:Windows 7 64位,Python版本3.2.5,PyWin32-218和cherrypy版本3.6.0。

我将CherryPy的windows服务示例(CP3.1)复制为windows服务,发现该服务几乎立即启动和停止。经过一番修改,我创建了一个静态日志文件,用于调试(因为服务运行在与原始脚本不同的目录中),并得到了以下内容:

>[05/Feb/2015:16:29:05] ENGINE Bus STARTING
>[05/Feb/2015:16:29:05] ENGINE Error in 'start' listener   <cherrypy._cpchecker.Checker object at 0x0000000002556278>
>Traceback (most recent call last):
>  File "C:Python32libsite-packagescherrypyprocesswspbus.py", line 205, in publish
>    output.append(listener(*args, **kwargs))
>  File "C:Python32libsite-packagescherrypy_cpchecker.py", line 39, in __call__
>    method()
>  File "C:Python32libsite-packagescherrypy_cpchecker.py", line 176, in check_static_paths
>    % (msg, section, root, dir))
>  File "C:Python32libwarnings.py", line 18, in showwarning
>    file.write(formatwarning(message, category, filename, lineno, line))
>AttributeError: 'NoneType' object has no attribute 'write'
>
>[05/Feb/2015:16:29:05] ENGINE Started monitor thread '_TimeoutMonitor'.
>[05/Feb/2015:16:29:05] ENGINE Serving on http://0.0.0.0:8080
>[05/Feb/2015:16:29:05] ENGINE Shutting down due to error in start listener:
>Traceback (most recent call last):
>  File "C:Python32libsite-packagescherrypyprocesswspbus.py", line 243, in start
>    self.publish('start')
>  File "C:Python32libsite-packagescherrypyprocesswspbus.py", line 223, in publish
>    raise exc
>cherrypy.process.wspbus.ChannelFailures: AttributeError("'NoneType' object has no attribute 'write'",)
>
>[05/Feb/2015:16:29:05] ENGINE Bus STOPPING
>[05/Feb/2015:16:29:06] ENGINE HTTP Server cherrypy._cpwsgi_server.CPWSGIServer(('0.0.0.0', 8080)) shut down
>[05/Feb/2015:16:29:06] ENGINE Stopped thread '_TimeoutMonitor'.
>[05/Feb/2015:16:29:06] ENGINE Bus STOPPED
>[05/Feb/2015:16:29:06] ENGINE Bus EXITING
>[05/Feb/2015:16:29:06] ENGINE Bus EXITED

在谷歌上搜索了这个错误,发现这是一个运行CherryPy 3.2的Windows服务,它也有同样的错误。做了更多的研究,发现windows服务的控制台输出指向"Nothing"。所以我添加了sys.stdout = open('stdout.log', 'a+')sys.stderr = open('stderr.log', 'a+')就在cherrypy.engine.start()之前你知道吗,它有效!

但现在我想CherryPy根本不登录。尝试了各种配置设置和代码,例如:log.screen = Noneserver.log_to_screen = Falsechecker.check_skipped_app_config = False,甚至

logger = cherrypy.log.access_log
logger.removeHandler(logger.handlers[0])

它们都不起作用,导致服务停止并给出与上述相同的错误。

我是错过了什么,还是真的不可能让日志静音?

遵循文档

基本上你的配置应该看起来像:

{'global': {
   'log.screen': False,
   'log.error_file': '',
   'log.access_file': ''
}}

我认为这与CherryPy日志记录没有太大关系。正如您所看到的,您的第一个堆栈跟踪在Python stdlib warnings模块中结束。它的目的是让开发人员知道满足了一些不需要的条件,但它们还不足以引发异常。它还提供了过滤警告消息的方法。以下是模块文档中的相关报价:

警告消息通常写入sys.stderr,但它们的处理可以灵活更改,从忽略所有警告到将它们变成异常。警告的处理可能因警告类别(见下文)、警告消息的文本以及发出警告的源位置而异。通常会抑制对同一源位置重复发出特定警告。

如果你看一下warnings.showwarning代码,你会看到这个:

def showwarning(message, category, filename, lineno, file=None, line=None):
    """Hook to write a warning to a file; replace if you like."""
    if file is None:
        file = sys.stderr
    try:
        file.write(formatwarning(message, category, filename, lineno, line))
    except IOError:
        pass # the file (probably stderr) is invalid - this warning gets lost.

CherryPy主动使用warnings,特别是在第一个堆栈跟踪中引用的配置检查器中。在您的服务环境中,sys.stderr似乎就是None。为了完全避免显示警告,您可以执行以下操作:

import warnings
warnings.simplefilter('ignore')

此外,如果你想继续重定向它们,你可能会发现这个问题很有用。

最新更新