如何在龙卷风中以无阻塞的方式实时有效地进行日志拖尾 python
How to do log tailing in realtime efficiently and in an unblocking manner in tornado python
我在一个基于龙卷风的 python 项目中有一个小网络应用程序,我需要实施实时日志拖尾(我坚持的少数事情之一)。该行为应该类似于 unix 的 tail -f
。如果它能在所有平台上工作,那会很好,但对于初学者来说,只需要 unix 就足够了。
我在 Whosebug 和其他地方搜索了很多方法,但没有找到我要找的东西。 Pythonic 解决方案不能很好地跟踪旋转日志或有时无法访问的文件。
因此我选择了 python subprocess
的方式。但是,由于缺少示例,我无法使用龙卷风的 Subprocess
class。所以我尝试了使用 run_in_executor
方法的正常子流程。我不确定这是否是一个好方法,或者我是否会有未来的问题。
def tail(self, file):
self.__process = subprocess.Popen(["tail", "-n", "1", "-f", file], stdout=subprocess.PIPE)
while 1:
line = self.__process.stdout.readline()
print(line)
# call a sync marked method and push line data
asyncio.sleep(.0001)
if not line:
asyncio.sleep(.5)
async def start_tail(self):
# start here
tornado.ioloop.IOLoop.current().run_in_executor(self.executor, self.tail, self.__log_path)
pass
这里的问题是我需要将 line
推入队列。该队列位于标记为 async
的函数中。要调用 async
方法,它说调用方法也应该是 async
。在那种情况下,我会得到一个错误:coroutines cannot be used with run_in_executor
。所以我对如何完成这项工作感到困惑。
我希望日志尾部像标准 linux tail -f
命令一样工作。它不应该阻止我的 Tornado 循环与其他正在进行的事情(例如网络请求、websocket 消息等)。我应该能够将 line
数据发送到我的代码库中的任何同步或异步方法。
使用 tornado.process.Subprocess
而不是 subprocess.Popen
(及其 STREAM
选项而不是 PIPE
)。这使您可以异步读取子进程:
async def tail(self, file):
self.__process = Subprocess(["tail", "-n", "1", "-f", file], stdout=Subprocess.STREAM)
while True:
line = await self.__process.stdout.read_until(b"\n")
do_something(line)
def start_tail(self):
IOLoop.current().spawn_callback(self.tail, self.__log_path)
我在一个基于龙卷风的 python 项目中有一个小网络应用程序,我需要实施实时日志拖尾(我坚持的少数事情之一)。该行为应该类似于 unix 的 tail -f
。如果它能在所有平台上工作,那会很好,但对于初学者来说,只需要 unix 就足够了。
我在 Whosebug 和其他地方搜索了很多方法,但没有找到我要找的东西。 Pythonic 解决方案不能很好地跟踪旋转日志或有时无法访问的文件。
因此我选择了 python subprocess
的方式。但是,由于缺少示例,我无法使用龙卷风的 Subprocess
class。所以我尝试了使用 run_in_executor
方法的正常子流程。我不确定这是否是一个好方法,或者我是否会有未来的问题。
def tail(self, file):
self.__process = subprocess.Popen(["tail", "-n", "1", "-f", file], stdout=subprocess.PIPE)
while 1:
line = self.__process.stdout.readline()
print(line)
# call a sync marked method and push line data
asyncio.sleep(.0001)
if not line:
asyncio.sleep(.5)
async def start_tail(self):
# start here
tornado.ioloop.IOLoop.current().run_in_executor(self.executor, self.tail, self.__log_path)
pass
这里的问题是我需要将 line
推入队列。该队列位于标记为 async
的函数中。要调用 async
方法,它说调用方法也应该是 async
。在那种情况下,我会得到一个错误:coroutines cannot be used with run_in_executor
。所以我对如何完成这项工作感到困惑。
我希望日志尾部像标准 linux tail -f
命令一样工作。它不应该阻止我的 Tornado 循环与其他正在进行的事情(例如网络请求、websocket 消息等)。我应该能够将 line
数据发送到我的代码库中的任何同步或异步方法。
使用 tornado.process.Subprocess
而不是 subprocess.Popen
(及其 STREAM
选项而不是 PIPE
)。这使您可以异步读取子进程:
async def tail(self, file):
self.__process = Subprocess(["tail", "-n", "1", "-f", file], stdout=Subprocess.STREAM)
while True:
line = await self.__process.stdout.read_until(b"\n")
do_something(line)
def start_tail(self):
IOLoop.current().spawn_callback(self.tail, self.__log_path)