2016-07-18 3 views
3

하위 프로세스에서 실행중인 python 프로그램의 추적에 액세스하려고합니다.하위 프로세스 하위 추적

The documentation는 말한다 : my_sub_program.py

Exceptions raised in the child process, before the new program has started to execute, will be re-raised in the parent. Additionally, the exception object will have one extra attribute called child_traceback, which is a string containing traceback information from the child’s point of view.

내용 : my_main_program.py

raise Exception("I am raised!") 

내용 : 나는 my_main_program.py을 실행하면, 나는 다음과 같은 오류가

import sys 
import subprocess 
try: 
    subprocess.check_output([sys.executable, "my_sub_program.py"]) 
except Exception as e: 
    print e.child_traceback 

:

Traceback (most recent call last): 
    File "my_main_program.py", line 6, in <module> 
    print e.child_traceback 
AttributeError: 'CalledProcessError' object has no attribute 'child_traceback' 

어떻게하면 서브 프로세스 프로그램 코드를 수정하지 않고 서브 프로세스의 추적을 액세스 할 수 있습니까? 즉, 내 전체 서브 프로그램 코드 주위에 큰 try/except 절을 추가하는 것을 피하고 싶지만 내 메인 프로그램에서 오류 로깅을 처리해야합니다.

편집 :sys.executable은 주 프로그램을 실행하는 인터프리터와 다른 인터프리터로 교체 가능해야합니다.

+0

Doc는 "새 프로그램이 실행되기 전에"라고 말합니다. 새 프로그램이 실행되는 동안 예외가 발생 했으므로 'child_traceback'이 없습니다. 일단 새로운 프로그램이 실행되면'CalledProcessError' 예외를 잡아서 다음과 같이해야합니다 : http://stackoverflow.com/questions/24849998/how-to-catch-exception-output-from-python-subprocess-check -output 'CalledProcessError.output'을 사용하여 출력 – mguijarr

+0

예에서'CalledProcessError.output'은 표준 출력만을 캡처했지만 Exception의 추적은 포착하지 않았습니다. – schreon

+0

이것은 출력이'stderr'에서 보내 졌기 때문일 것입니다. 위의 링크를 보내 주신 질문의 답변을 참조하십시오. – mguijarr

답변

0

다른 파이썬 프로세스를 시작할 때 multiprocessing 파이썬 모듈을 사용해 볼 수도 있습니다. 하여 Process 클래스를 하위 클래스라는이 대상 기능에서 예외를 얻을 매우 쉽습니다 :

from multiprocessing import Process, Pipe 
import traceback 
import functools 

class MyProcess(Process): 
    def __init__(self, *args, **kwargs): 
     Process.__init__(self, *args, **kwargs) 
     self._pconn, self._cconn = Pipe() 
     self._exception = None 

    def run(self): 
     try: 
      Process.run(self) 
      self._cconn.send(None) 
     except Exception as e: 
      tb = traceback.format_exc() 
      self._cconn.send((e, tb)) 
      # raise e # You can still rise this exception if you need to 

    @property 
    def exception(self): 
     if self._pconn.poll(): 
      self._exception = self._pconn.recv() 
     return self._exception 


p = MyProcess(target=functools.partial(execfile, "my_sub_program.py")) 
p.start() 
p.join() #wait for sub-process to end 

if p.exception: 
    error, traceback = p.exception 
    print 'you got', traceback 

트릭은 파이썬 서브 프로그램을 실행하는 대상 기능을하는 것입니다, 이것은 functools.partial를 사용하여 수행됩니다.

+0

이 솔루션을 사용하면 하위 프로세스가 주 프로그램과 다른 인터프리터에서 실행될 수 있습니까? 당신의 제안을 보았을 때 필자는 필자의 예에서'sys.executable'을 사용하는 것을 오도하는 것으로 나타났습니다. 그러나, 내 질문의 맥락에서, 나는 주 프로세스보다 다른 가상 환경에서 스크립트를 시작해야합니다. (메인 프로세스는 일종의 스케쥴러가 될 것이다.) – schreon

+0

사실'다중 처리 '는 POSIX 플랫폼에서'os.fork'를 수행하기 때문에 새로운 가상 환경이 아닙니다. 그러나 프로세스 사이에 공유되는 데이터의 양을 제한 할 수 있습니다. 'Process'객체를 일찍 시작하면됩니다. 이것은 당신의 필요에 충분히 부합 할 수 있습니다. – mguijarr

+0

일종의 스케줄러인데 [Celery] (http : /www.celeryproject.org/) – mguijarr