У меня есть небольшое веб-приложение в проекте Python, основанном на торнадо, и мне нужно реализовать отслеживание журналов в реальном времени (одна из немногих вещей, в которых я застрял).Поведение должно быть похоже на Unix tail -f
.Было бы хорошо, если бы это работало на всех платформах, но для начала достаточно просто UNIX.
Я искал много способов сделать это на stackoverflow и еще где, но не нашел то, что я ищу.Pythonic решения не годятся для отслеживания вращающихся журналов или файлов, которые иногда недоступны.
Поэтому я пошел по пути python subprocess
.Однако я не мог использовать класс Subprocess
торнадо из-за отсутствия примеров.Итак, я попробовал нормальный подпроцесс с 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 от других происходящих событий (таких как веб-запросы, обмен сообщениями через веб-сокет и т. Д.).Я должен быть в состоянии отправить line
данные любому методу синхронизации или асинхронности в моей кодовой базе.