2010-03-19 2 views
7

"형식 문자열에 대해 충분하지 않은 argumenst"를 발생시키는 로깅 호출을 쉽게 찾을 수 있습니다. 내 워크 스테이션에서 logging/__init__.py을 수정하여 소스에서 줄을 쉽게 찾을 수 있도록 msg를 인쇄했습니다.파이썬 로깅 라이브러리에서 "충분하지 않은 인수 ..."를 찾는 쉬운 방법

하지만 파이썬 표준 라이브러리를 바꿀 수 없거나 쉽게 pdb를 실행할 수없는 테스트 환경에서해야 할 일이 있습니까?

참고 : 추적 기록은 의미가 없으며 로깅 라이브러리에 의해 구별됩니다. 여기 는 역 추적입니다 :

File "/usr/lib/python2.6/logging/handlers.py", line 71, in emit 
    if self.shouldRollover(record): 
    File "/usr/lib/python2.6/logging/handlers.py", line 144, in shouldRollover 
    msg = "%s\n" % self.format(record) 
    File "/usr/lib/python2.6/logging/__init__.py", line 648, in format 
    return fmt.format(record) 
    File "/usr/lib/python2.6/logging/__init__.py", line 436, in format 
    record.message = record.getMessage() 
    File "/usr/lib/python2.6/logging/__init__.py", line 306, in getMessage 
    msg = msg % self.args 
TypeError: not enough arguments for format string 

그리고 여기에 알렉스에 의해 제안 오류를

try: 
     if self.shouldRollover(record): 
      self.doRollover() 
     logging.FileHandler.emit(self, record) 
    except (KeyboardInterrupt, SystemExit): 
     raise 
    except: 
     self.handleError(record) 

솔루션을 잡아 표준 라이브러리의 코드입니다 : 나는의 getMessage 포장 한이를 인쇄 msg와 args. 여기에 코드입니다 : 일반적으로

def print_log_record_on_error(func): 
    def wrap(self, *args, **kwargs): 
     try: 
      return func(self, *args, **kwargs) 
     except: 
      import sys 
      print >>sys.stderr, "Unable to create log message msg=%r, args=%r " % (
           getattr(self, 'msg', '?'), getattr(self, 'args', '?')) 
      raise 
    return wrap 
import logging 
logging.LogRecord.getMessage = print_log_record_on_error(logging.LogRecord.getMessage) 
+0

이 질문과 게시 솔루션을 이용해 주셔서 감사합니다. "TypeError : 형식 문자열에 대한 인수가 충분하지 않습니다"라는 문제에 직면했을 때 나는 네 번째로 그런 것들을 감지하는 현명한 방법을 찾기 시작했습니다. 귀하의 게시물은 Google 검색 결과의 첫 번째 화면에서 발견되었습니다. 나는이 예외를 처리하고 사용자 코드에서이 문제가 발생하는 위치에 대한 정보를 제공하기 위해 로깅 모듈을 업데이트해야한다고 생각합니다. – vvladymyrov

+0

@vvladymyrov 환영합니다. 코드가 ou에 유용하다는 사실을 알려 주셔서 감사합니다. –

답변

2

가 (당신이 언급 포함) 예외를 잡을 수있는 가장 좋은 방법은 try/except 문의 try 절에 용의자 코드를 삽입하는 것입니다은; except 절에서 traceback 모듈 또는 다른 방법을 사용하여 잘못된 문구를 찾아 낼 수 있습니다.

예외가 잡히지 않는 예외는 결국 sys.excepthook으로 끝납니다. 이는 필요에 따라 추적을 얻는 데 사용할 수있는 또 다른 방법입니다.

그러나 나는 logging 모듈에 "예외가 전파되도록하십시오"라고 말하는 구조화 된 방법이 없다고 생각합니다.이 경우 가장 좋은 내기는 아마 원숭이 패치 일 것입니다. 즉, 일반적으로 은 런타임에 "파이썬 표준 라이브러리 변경"을 할 수 있습니다. 식별자를 자신의 함수/classes/etc에 설정하여 표준 패키지를 래핑합니다.

import logging, traceback 

orgwarn = logging.warning 
def mywarn(msg, *a): 
    try: res = msg % a 
    except TypeError: 
    traceback.print_exc() 
    return orgwarn(msg, *a) 
logging.warning = mywarn 

청소기 가지 방법이 있습니다,하지만 그들은 (다소 번거로울 수 예를 들어, 자신의 로거 클래스를 만들 수 있습니다 : 예를 들어, 당신이 알고있는 경우 문제가 logging.warning 호출하는 "개념의 증거"함께 monkeypatch 일 수 있습니다 루트 로거로 설정). 원숭이 패치는 프로덕션 환경에서 작동하는 좋은 방법이 아닙니다 (시스템 업그레이드에 취약하고 이해 및 유지 관리가 어려울 수 있음 등). 그러나 디버깅 및 테스트 목적으로는 적합 할 수 있습니다.

+0

좋은 생각, 나는 getMessage 함수를 감싸서 msg와 args를 출력하고 버그를 발견했다. 고맙습니다. –

0

"형식 문자열에 대해 충분하지 않은 argumenst"를 발생시키는 로깅 호출을 찾으려면.

모든 로깅 호출 소스를 grep합니다. 많은 것이 없습니다 : .info(, .warn(, .debug(, .error(, .critical(, .exception(, .log(.

이러한 메소드 중 하나에는 충분한 인수가없는 형식이 있습니다. 메시지에는 "%"형식 지정 연산자가 있으므로 일반적으로 쉽게 위치를 알아낼 수 있습니다.

응용 프로그램이 모든 로거를 호출하는 데 일관성이 있다면 logger은 더 쉽게 grep을 수행 할 수 있으므로 logger.입니다.

관련 문제