2017-10-19 9 views
1

각 하위 프로세스에 대한 로그를 생성하려는 동시 실행 프로그램이 있습니다. 우선 설치 프로그램을 설명하고 내가 직면 한 문제를 설명합니다. 여기 내 기본 모듈은 다음과 같습니다Python의 멀티 스레딩/로깅 모듈에 대한 문제

mp_handler.py :

import logging 
import multiprocessing as mp 

def mp_handler(target, args_list): 

    # configure logs 
    for args in args_list: 
     logger_id = args[0] # first arg suffices to id a process, in my case 
     logger = logging.getLogger(logger_id) 
     handler = logging.FileHandler(logger_id + '.log') 
     logger.setLevel(logging.INFO) 
     logger.addHandler(handler) 

    mp.set_start_method('spawn') # bug fix, see below   

    # build each process 
    for args in args_list: 
     p = mp.Process(target = target, args = args) 
     p.start() 

mp_worker.py :

import logging 
from deco_module import deco 
from my_module import function_with_open_cv 

@deco 
def mp_worker(args): 
    logger_id = arg[0] 
    logger = logging.getLogger(logger_id) 

    log.info("Information about process %s" % log_id)   

    # do a lot of stuff with openCV3 
    function_with_open_cv(args)  # also logs to this child's log file 

deco_module.py :이 모듈은 일부 예외 처리를 수행하고 내가 왜 수도 아무 생각이 없다 간섭하지만 나는 그것을 위해 그것을 포함시킬 것이라고 생각한다.

from functools import wraps 
import logging 

def deco(function): 

    @wraps(function) 
    def wrapper(*args): 
     logger_id = *args[0] 
     logger = logging.getLogger(logger_id) 
     try: 
      function(*args) 
     except: 
      logger.info('a message in case the child fails.') 

    return wrapper 

이제 내 문제에 관해서. 이 게시물에 설명 된 오류가 발생했습니다 : https://github.com/opencv/opencv/issues/5150. 따라서 줄을 mp_handler()에 썼습니다.

디버깅이 끝난 후 해당 행에서 행 mp_worker()에서 부모에서 생성 된 값 (예 : mp_handler())을 생성하는 대신 새 로거를 생성하는 것으로 나타났습니다. 부모 모듈과 하위 모듈 모두에 hex(id(logger))을 인쇄하여이를 볼 수 있었고 메모리의 위치가 다른 것을 볼 수있었습니다. 사실, 내가 말했듯이, mp.set_start_method('fork')을 쓰는 것은이 문제를 피한다. (이것은 내란으로 산란이 로거를위한 새로운 공간을 창출 할 것이므로 매우 불만 스럽다.)

주요 문제 : 문제는 OpenCV를 위해 '스폰'로 설정해야하는 시작 방법이 필요하지만 그 사이에 로그 통신을 토글해야한다는 것입니다. 모듈 (즉, mp_worker가 정확한 logger_id를 인식하여 올바른 파일에 기록하려면)? 좋은 연습의 일환으로 모든 로깅 구성을 하위 및 하위 모듈 모두에서 유지하려고합니다.

2 차적인 문제 : OpenCV가 필요하다는 사실을 무시하고 메소드를 'fork'로 설정한다고 가정합니다. 이 경우에 나는 function_with_open_cv() 함수의 logging.info() 문 중 아무 것도 로그에 도달하지 않는다는 것을 알아 차렸다. 따라서 포크로 설정하는 것이 좋습니다라고 가정 할 경우 여기에있는 작업은 무엇입니까? 편집 : 고정! 이것은 또한 OpenCV에 의한 것입니다. 그래서 문제는 여전히 존재합니다 ... 어떻게 스폰 프로세스를 사용하고 로거 ID를 잃지 않습니까?

정말 고마워요!

답변

-1

프로세스가 생성되기 전에 로깅을 구성하면 안됩니다. 올바르게 수행하는 방법의 예는 the documentation을 참조하십시오. 이것은 Python 3에 적용되지만, Python 2에서 실행해야하는 경우 logutils package을 사용하면 QueueListenerQueueHandler 클래스를 제공합니다.

로깅 요리 책에는 multiprocessing과 함께 로깅을 사용하는 것과 관련된 예제 코드가 포함되어 있습니다.

+0

여기서 잘못된 점을 자세히 설명하면 훨씬 더 나은 대답이 될 것입니다. –

+0

@SamHartman 그건 downvote 이유가 없어요. 스레딩, 분기 및 상호 작용을 합리적으로 간략하게 설명하는 것은 실제로 불가능합니다. –

+0

나는 당신이 질문에 대답하지 않았다고 생각했기 때문에 나는 다운 받았다. 특히 나는 그 질문의 일부가 무슨 일이 일어나고 있는지를 물었다. 그러나 독서는 OP가 단지 고치는 법을 물었던 것을 안다. 충분히 복잡한 응용 프로그램에서, 나는 이것이 좋은 대답이라고 생각하지 않지만, 나는 downvote를 후회한다. 편집을하지 않으면 변경되지 않습니다. –