今天在定位一个问题的时候发现,Python中logging模块的StreamHandle对于控制台转向输出,默认是输出到stderr的,logging内的源代码如下
class StreamHandler(Handler):
"""
A handler class which writes logging records, appropriately formatted,
to a stream. Note that this class does not close the stream, as
sys.stdout or sys.stderr may be used.
"""
def __init__(self, strm=None):
"""
Initialize the handler.
If strm is not specified, sys.stderr is used.
"""
Handler.__init__(self)
if strm is None:
# !!!问题就出在这里,默认情况下,控制台输出是输出到stderr,而不是stdout的!
strm = sys.stderr
self.stream = strm
def flush(self):
"""
Flushes the stream.
"""
if self.stream and hasattr(self.stream, "flush"):
self.stream.flush()
这在绝大部分情况下都没什么问题,但对于使用了logging模块并且使用console Handle的Python程序,如果其他程序通过subprocess启动并执行它,并实时监听其运行输出时,要注意优先监其标准错误(stderr)输出。当然还有个办法,就是在初始化控制台StreamHandle时,强制指定logging输出到stdout,毕竟stdout更符合常规意义上的理解和认知,代码:
console = logging.StreamHandler(strm = sys.stdout)
进一步的,在Django的logging配置中,对于console handle配置,也可以通过指定strm参数来强制使用stdout作为控制台转向输出的文件句柄:
......
'console': {
'level' : 'DEBUG',
'class' : 'logging.StreamHandler',
'formatter' : 'simple',
'strm' : sys.stdout
},
......