环境: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 = None
、server.log_to_screen = False
、checker.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')
此外,如果你想继续重定向它们,你可能会发现这个问题很有用。