2015-09-28 213 views
4

这是一个python问题,也是一个linux/BSD问题。是否有可能输出到监视流而不是标准输入,标准输出和标准错误? (python)

我有一个python脚本有两个线程,一个从网上下载数据,另一个通过串口发送数据到设备。这两个线程都使用python的logging模块将很多状态信息打印到标准输出。

我想要的是两个终端窗口并排打开,并让每个终端窗口显示来自一个线程的输出,而不是将这两个消息从两个交错的窗口中交错。

是否有除标准输入以外的文件描述符,标准输出& stderr写入并连接到其他终端窗口?也许这个愿望更好地用GUI来实现?

我不知道该如何开始。

编辑:我试着写状态消息到两个不同的文件,而不是打印到标准输出,然后在其他终端窗口中使用tail -f监视这两个文件,但这不适用于实时监控,因为文件aren直到你给他们打电话close()

+0

“我有一个暗示,有可能通过将状态消息写入两个单独的文件来实现此目的”。我以为你还没有尝试过呢?您可以设置日志记录以让每个线程都记录到单独的文件(通过让每个线程使用单独的记录器)。如果您想要使用GUI方式,您可能需要查看更具异国情调的日志处理程序,例如QueueListener。 – Evert

+0

我刚刚尝试过使用python的内置文件编写方法,但它不起作用(请参阅上面的编辑)。 – beibei2

+2

如果你不得不调用'close()',那可能意味着你没有使用日志文件处理程序?你也可以调用文件指针上的'fp.flush()'来强制一行写入文件。 – Evert

回答

2

首先,自定义您的日志格式化程序以包含线程ID字段(https://docs.python.org/2/library/logging.html#logrecord-attributes)。然后将您的日志记录目标更改为某个文件而不是stdout。

# A simple logger as print 
import logging 
import logging.handlers 

hdr = logging.FileHandler(filename='output.log') 
hdr.setFormatter(logging.Formatter('[%(asctime)s] thread=%(thread)s:%(levelname)s: %(message)s')) 
logger = logging.getLogger(__name__) 
logger.addHandler(hdr) 
logger.setLevel(logging.DEBUG) 

import threading 


def func(): 
    logger.info('test message') 


for i in range(2): 
    threading.Thread(target=func).start() 

你的日志输出可能看起来像现在这样:

% tail -f output.log 
[2015-09-28 15:14:49,782] thread=4344852480:INFO: test message 
[2015-09-28 15:14:49,782] thread=4349059072:INFO: test message 

运行脚本,打开两个单独的终端,使用命令tail -f output.log | grep thread=<THREAD_ID>来监视线程ID登录。

+0

不错!我没有想到这样做,这是一个很好的方式来获得所需的显示,而不需要将输出分割成多个日志文件。经过测试,它的工作原理! – beibei2

0

默认缓冲文件写入操作,所以文件无效,直到缓冲区已满,文件关闭或您明确地在文件上调用flush()

但不管怎么说:不要使用直接文件访问,如果你想日志到一个文件中,使用一个logging.StreamHandler有打开的文件作为流,或更好,一个logging.FileHandler。两者都会照顾冲洗文件。

相关问题