2013-07-16 3 views
0

응용 프로그램은 파이썬 로깅을 사용합니다. 그것은 다른 모듈을 가지고 있고 각 모듈은 최상위 계층에 루트를 가진 로거를 가지고 있습니다. 타사 API와 통신하는 모듈이 3 개 있습니다. 제 3 자 API의 요청/응답 로그를 추적하는 데 많은 시간이 소요됩니다. 따라서 로그 메시지를 기반으로 다른 로그 파일로 로그를 리디렉션해야합니다. 이렇게하면 API 요청/응답 로그 추적이 단순 해집니다. 로그 수준을 기반으로하는 로그의 리디렉션은 매우 일반적이지만 로그 메시지 콘텐츠를 기반으로 API 특정 로그를 다른 로그 파일로 리디렉션하는 효율적인 설계를 내놓을 수 없습니다. 아래는 요구 사항을 달성하는 데 사용할 수있는 접근 방식입니다. 응용 프로그램의 파이썬 로깅 설정시 python logging - 로그 메시지를 기반으로 다른 파일로 로그 리디렉션

class APILevelLogHandler(logging.Handler): 
    def __init__(self): 
     logging.Handler.__init__(self) 
    def emit(self, record): 
     import re, os, socket 
     logFileList = [] 
     matchObj = re.search('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', str(record.msg)) 
    logPath = "/tmp/" 
    try: 
     if matchObj and socket.inet_aton(matchObj.group()): 
      if not matchObj.group() in logFileList: 
       logFileList.append(matchObj.group()) 
       if not os.path.isdir(logPath): 
        try: 
         os.makedirs(logPath) 
        except OSError: 
         print "Exception", ex, callstack.ExcepCallStack() 
      if "dataReceived" in record.msg or "send" in record.msg: 
       with open(str(os.path.join(logPath, matchObj.group()+".log")), 'a') as f: 
        f.write(record.msg + '\n') 
    except Exception, ex: 
     print "Exception", ex, callstack.ExcepCallStack() 

는, 핸들러는 나에게 달성 위의 요구 사항에 더 나은 디자인을 제안하십시오

logger = logging.getLogger('') 
logger.addHandler(APILevelLogHandler()) 

Output.log 
API test1 1.1.1.1 data send 
API test2 2.2.2.2 data send 
API test1 1.1.1.1 data received 
API test1 1.1.1.1 data send 
API test2 2.2.2.2 data received 
API test1 1.1.1.1 data received 

Expected output 
1.1.1.1.log 
API test1 1.1.1.1 data send 
API test1 1.1.1.1 data received 
API test1 1.1.1.1 data send 
API test1 1.1.1.1 data received 

2.2.2.2.log 
API test2 2.2.2.2 data send 
API test2 2.2.2.2 data received 

로 루트 로거에 추가됩니다.

감사합니다, 란잔

하나 더 가능성이 솔루션 : 나는 핸들러 RotatingFileHandler에서 제공하는 동일한 기능을 사용하려면 접근 위

그때 내가 가진, 기존의 프로세스에 추가 오버 헤드를 추가합니다 기능을 다시 작성하십시오. 그래서 하나의 모듈에서 로깅을 수행하면 잘 작동하는 제안이 하나 더 있는데, 제 경우 로깅은 여러 모듈에서 수행됩니다. 따라서 일반적인 로깅 설정에서 로그를 리디렉션해야합니다. 여러 모듈에 대해 가능한 다른 방법이 있다면 알려주십시오.

logFileName = "logFileName_extracted_from_message" 
    self.apilevelLogger = logging.getLogger(logFileName) 
    if any(isinstance(item, logging.handlers.RotatingFileHandler) for item in logging.getLogger('').handlers): 
     handler = logging.handlers.RotatingFileHandler(logFileName, maxBytes=10e6, backupCount=3) 
     self.apilevelLogger.addHandler(handler) 
     self.apilevelLogger.setLevel(logging.INFO) 

    self.apilevelLogger.info("API test1 1.1.1.1 send data") 

두 번째로 접근하면 no. 생성 된 로거의 번호는 아니오와 같습니다. 생성 된 로그 파일의 모든 모듈에 동일한 코드를 추가하는 대신 추가 개선의 여지가 있기를 바랍니다. 효율성과 디자인을 개선하는 데 도움주세요.

감사합니다, 란잔

+0

코드를 올바르게 포맷하십시오. –

답변

0

당신이 (간체 스크립트 구조) 같은 것을 시도해 볼 수도 있습니다 :

def writelog(text, file): 
    # simplified version 
    filehandle = open(file, 'a') # 'a' for 'append' 
    filehandle.write(text) 
    filehandle.close() 

# (...) will be the group(1) of the match and the filename 
matchObj = re.search('(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', str(record.msg)) 
filename = matchObj.group(1) 

# perform further tests to see if you want to write the message to the log 
if ... : 
    writelog(record.msg, filename) 

가 도움을합니까를?

+0

신속한 유용한 답변을 보내 주셔서 감사합니다. 또한 로그 메시지를 기반으로 로그의 리디렉션이 처리기에서 수행되어야하는지 여부를 알고 싶습니다. – user2587275

+0

나머지 코드는 모르므로 말하기 어렵습니다. 내가 볼 수있는 한, 핸들러에 코드 라인을 삽입하는 것에 반대하는 것은 없습니다. – adbar

+0

다른 해결책이 하나 있습니다. 귀중한 의견을 제공해주세요. 란얀 – user2587275

관련 문제