現(xiàn)象:
pycharm_logging.png
原因:
在PyCharm的設置中, 運行窗口會把stderr
的信息輸出為紅色:
pycharm_error.png
只要把Foreground
取消掉就可以了
本質(zhì):
那么現(xiàn)在的問題是, 為什么Scrapy
的的log信息會出現(xiàn)在stderr
中?
首先我們看一下Scrapy log的配置:
def configure_logging(settings=None, install_root_handler=True):
# 刪除不必要的信息
if install_root_handler:
logging.root.setLevel(logging.NOTSET)
handler = _get_handler(settings)
logging.root.addHandler(handler)
def _get_handler(settings):
""" Return a log handler object according to settings """
filename = settings.get('LOG_FILE')
if filename:
encoding = settings.get('LOG_ENCODING')
handler = logging.FileHandler(filename, encoding=encoding)
elif settings.getbool('LOG_ENABLED'):
handler = logging.StreamHandler()
else:
handler = logging.NullHandler()
formatter = logging.Formatter(
fmt=settings.get('LOG_FORMAT'),
datefmt=settings.get('LOG_DATEFORMAT')
)
handler.setFormatter(formatter)
handler.setLevel(settings.get('LOG_LEVEL'))
if settings.getbool('LOG_SHORT_NAMES'):
handler.addFilter(TopLevelFormatter(['scrapy']))
return handler
Scrapy
的默認設置是給root logger
根據(jù)配置信息添加一個Handler
, 默認為
handler = logging.StreamHandler()
而StreamHandler
的默認設置是:
def __init__(self, stream=None):
"""
Initialize the handler.
If stream is not specified, sys.stderr is used.
"""
Handler.__init__(self)
if stream is None:
stream = sys.stderr
self.stream = stream
所以我們的log信息都跑到stderr
中去了.
現(xiàn)在知道原理之后, 我們可以用更加Pythonic的方法解決這個問題:
import sys
sys.stderr = sys.stdout
這樣, stdout
和 stderr
都指向同一個file descriptor
, 所有的log 也都會寫入這個file descriptor
.