Программа, вызываемая с помощью сообщений подпроцесса — регистратора, не печатается?

#python #logging #subprocess

#python #ведение журнала #подпроцесс

Вопрос:

существует проблема с получением сообщений из регистратора программы, если эта программа вызывается с помощью подпроцесса.

Вот программа BooFoo.py который использует регистратор для печати сообщений в файл и окно консоли:

 import logging
LOG_FILENAME = 'example.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
logger = logging.getLogger('main')
logger.addHandler(logging.StreamHandler())
print 'print foo'
logger.info('logger boo')
  

Вот программа CallBooFoo.py:

 import subprocess
proc = subprocess.Popen(['python BooFoo.py'], bufsize=512, stdin = None, 
     stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell=True)
proc_out, proc_err = proc.communicate()
print proc_out
  

«logger boo» не печатается с CallBooFoo.py. Есть идеи, как это исправить? Использование os.system работает, но не является решением по некоторым другим причинам.

Ответ №1:

logging.StreamHandler по умолчанию выполняется запись в стандартную ошибку, а не стандартный вывод. Вы можете изменить это на стандартный вывод, используя logging.StreamHandler(sys.stdout) вместо этого.

Вы также можете сохранить свой код как есть и вывести значение proc_err вместо (или в дополнение к) proc_out в вызывающем процессе. Это покажет стандартную ошибку дочернего процесса.

Если вам нужно видеть как stdout, так и stderr, смешанные вместе, вы можете изменить вызывающий процесс на:

 proc = subprocess.Popen(['python BooFoo.py'], bufsize=512, stdin = None, 
     stdout = subprocess.PIPE, stderr = subprocess.STDOUT, shell=True)
proc_out, proc_err = proc.communicate()
print proc_out
  

Комментарии:

1. Отлично! Теперь я вижу, что это также есть в документах. Но мне все еще интересно, почему StreamHandler направляет обычные сообщения в stderr?

2. @bitman Вероятно, поскольку logging предполагается, что он используется для сообщения о проблеме / сообщениях о выполнении пользователю, что является целью stderr . stdout предназначен для фактического вывода данных.