Вот моя проблема. У меня есть приложение, которое печатает некоторые трассы на стандартный вывод, используя модуль logging
. Теперь я хочу иметь возможность читать эти трассы одновременно, чтобы ждать определенной трассировки, в которой я нуждаюсь.
Это для целей тестирования. Так, например, если желаемая трассировка не возникает примерно через 2 секунды, тест завершается с ошибкой.
Я знаю, что могу читать выходные данные других скриптов, используя что-то вроде этого:
import subprocess
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
line = p.stdout.readline()
print line
if line == '' and p.poll() != None:
break
Но как я могу сделать что-то подобное из самого скрипта? Заранее спасибо.
РЕДАКТИРОВАТЬ
Поэтому, поскольку моя проблема ожидала появления определенной трассировки во время работы приложения Python, и поскольку я не мог найти простой способ сделать это из самого приложения, я решил запустить приложение (как это предлагается в комментариях) из другого скрипт.
Модуль, который я нашел очень полезным и более простым в использовании, чем модуль subprocess
, является pexpect
модулем.
Если вы хотите сделать предварительную обработку сообщений журнала, вы можете сделать что-то вроде:
#!/usr/bin/python
import sys
import logging
import time
import types
def debug_wrapper(self,msg):
if( hasattr(self,'last_time_seen') and 'message' in msg):
print("INFO: seconds past since last time seen "+str(time.time()-self.last_time_seen))
self.last_time_seen = time.time()
self.debug_original(msg)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logger = logging.getLogger("test")
logger.debug_original = logger.debug
logger.debug = types.MethodType(debug_wrapper, logger)
while True:
logger.debug("INFO: some message.")
time.sleep(1)
Это работает, заменив исходную функцию отладки объекта logger на вашу пользовательскую функцию debug_wrapper, в которой вы можете делать любую необходимую обработку, например, сохраняя последний раз, когда вы видели сообщение.
Если вы хотите записать вывод из инструкции print в другом коде Python, вы можете перенаправить sys.stdout
в строку, такую как файл-объект, следующим образом:
import io
import sys
def foo():
print("hello world, what else ?")
stream = io.StringIO()
sys.stdout = stream
try:
foo()
finally:
sys.stdout = sys.__stdout__
print(stream.getvalue())
Вы можете сохранить вывод сценария в файл в режиме реального времени, а затем прочитать его содержимое в скрипте в режиме реального времени (так как содержимое в выходном файле обновляется динамически).
Чтобы сохранить вывод сценария в файл в режиме реального времени, вы можете использовать unbuffer, который поставляется с пакетом ожидания.
sudo apt-get install expect
Затем при запуске скрипта используйте:
unbuffer python script.py > output.txt
Вы должны просто распечатать вывод в скрипте, который будет динамически обновляться в выходном файле. И, следовательно, каждый раз читайте этот файл.
Кроме того, используйте> для перезаписи старого или создания нового файла и >> для добавления содержимого в ранее созданный файл output.txt.