2011-07-26 2 views
1

로깅 모듈을 통해 일부 로그에 상황 별 정보를 추가하려고합니다. 로그의 각 줄 옆에 projectid를 볼 수 있어야하며 매일 2 만 개가 넘는 프로젝트가 생성되므로이 데이터가 실제로 도움이됩니다. 이를 위해 logging.Filter 모듈의 파생물을 만들었습니다.django의 logging.filters에 동적 요소 추가 1.3

import logging 

class MTFilter(logging.Filter): 

def __init__(self, projectid=0): 
    self.projectid = projectid 

def filter(self, record): 
    record.projectid = self.projectid 
    return True 

여기 settings.py

LOGGING = { 
    'version': 1, 
    'disable_existing_loggers': True, 
    'filters': { 
     'project': { 
      '()': 'app.proj.logging.mtfilter.MTFilter', 
     }, 
    }, 
    'formatters': { 
     'projectformat': { 
      'format': '%(asctime)s %(levelname)8s PID[%(projectid)d] %(name)s[%(funcName)s]: %(message)s', 
     }, 
    }, 
    'handlers': { 
     'null': { 
      'level': 'DEBUG', 
      'class': 'django.utils.log.NullHandler', 
     }, 
     'project-log': { 
      'level': 'DEBUG', 
      'class': 'logging.handlers.RotatingFileHandler', 
      'formatter': 'projectformat', 
      'filename': os.path.join(SITE_ROOT, '../logs/django.log'), 
      'filters': ['project'], 
      'maxBytes': 1024*1024*16, #16Mb 
     }, 
    }, 
    'loggers': { 
     '': { 
      'handlers':  ['null'], 
      'level':  'DEBUG', 
      'propagate': True, 
     }, 
     'proj': { 
      'handlers': ['project-log'], 
      'level':  'DEBUG', 
     }, 
    } 
} 

에서 그리고 내보기에 내 LOGGING 변수의 내가 사용 Logging.filters에 'projectid'에 대한 모든 값을 넣어하지 않음으로써 다음

logger = logging.getLogger('proj') 
logger.info('Log Message') 

.project 기본 형식 값인 '0'을 얻습니다. 로그 결과는 다음과 같다 : 내가하고 싶은 무엇

2011-07-26 02:41:44,488  INFO PID[0] proj[view]: Log Message 

는 예를 들어, 동적으로 어떻게 든 'projectid'값을 잡아이다. 로거 객체를 만들거나 미들웨어를 사용할 때 어떻게해야할지 모릅니다. 누구든지 제안이 있습니까?

+0

입니다. 자체 로깅은 로그에 컨텍스트 정보를 추가하는 여러 가지 방법을 제공합니다, 예를 들어'LoggingAdapter' 또는 로깅 호출에 대한 'extra' 키워드 arg. 그러나 (예 : 타사 라이브러리에서) 소스에 액세스 할 수없는 로깅 호출에 컨텍스트 정보를 추가하려면 제안 된 방법이 있습니다. –

답변

2

내가 뭘하고 싶은지 동적으로 'projectid'값을 어떻게 든 잡는 것, 예. 로거 객체를 만들거나 일부 미들웨어를 사용할 때 나는 단지 어떻게해야할지 모릅니다.

로거를 만들 때 일회성 작업이므로 적절하지 않습니다. 아마도 현재 프로젝트 ID를 필터로 가져 오는 방법을 찾아야 할 것입니다. 예를 들어, 생성시 필터에 레코드를 전달하는 대신 필터가 호출하여 프로젝트 ID를 가져 오는 호출 가능 디자인을 사용할 수 있습니다. 예를 들어 :

class ProjectFilter(logging.Filter): 
    def __init__(self, func): 
     self.func = func 

    def filter(self, record): 
     record.projectid = self.func() 
     return True 

이 호출은 현재 컨텍스트에서 프로젝트 ID를 얻는 방법을 알고 무엇이든 될 수있다 (예를 들어 지역 스레드 - 그가 장고의 핵심 팀에 의해 승인되지 비록, 그것은 스레드 지역 주민을 위해 발명되었다 무엇 , 그리고 Flask와 같은 다른 프레임 워크에 의해 꽤 성공적으로 사용됨). 나는 callable이 어떻게 작동 할지를 제안하는 당신의 어플리케이션에 대해 충분히 알지 못한다.

+0

감사합니다. Vinay , 그것은 단지 기분이 좋지 않지만, 너무 단순한 것에 지나치게 복잡하게 보인다. 나는 그것이 내가했던 것을이기 때문에 대답을 받아 들였다. –

0

가장 우아한 해결책은 아니지만 로깅 소스를 검토 한 결과 '추가'매개 변수를 통해 상황에 맞는 정보를 추가 할 수 있다는 것을 알았습니다.

logger.info('A long entry', extra={'projectid': 1}) 

난 그냥 로그 항목 방법을 무시하고 존재하는 경우 '추가'매개 변수를 추가 내 자신 로거 객체를 유도 할 수 있습니다.

내가 사용 LogAdaptors에 같은 것이다하지만 내가 사용 파이썬 버전은 내가 당신의 코멘트를 참조 2.5 배 :(