2010-02-25 6 views
3

우리는 소비자의 여러 요청을 동시에 처리하는 웹 로직 배치 애플리케이션을 보유하고 있습니다. 우리는 puposes를 기록하기 위해 log4j를 사용합니다. 지금 우리는 여러 요청에 대해 단일 로그 파일에 로그인합니다. 로그가 단일 파일에있는 모든 요청에 ​​대해 특정 요청에 대한 문제를 디버깅하는 일이 번거로워집니다.Log4j : 요청 당 하나의 로그 파일

요청 당 하나의 로그 파일을 만들 계획입니다. 소비자가 처리를 수행해야하는 요청 ID를 보냅니다. 이제 실제로 여러 명의 소비자가 요청 ID를 애플리케이션에 전송할 수 있습니다. 그래서 질문은 요청에 따라 로그 파일을 seggregate하는 방법입니다.

& 때마다 프로덕션 서버를 중지 할 수 없으므로 날짜 시간 소인이나 요청 ID가있는 재정의 된 파일 appender를 사용하는 것이 배제됩니다. http://veerasundar.com/blog/2009/08/how-to-create-a-new-log-file-for-each-time-the-application-runs/

나는 이러한 대안 장난 시도 :

http://cognitivecache.blogspot.com/2008/08/log4j-writing-to-dynamic-log-file-for.html

http://www.mail-archive.com/[email protected]/msg05099.html

이러한 접근 방식은 원하는 결과를 제공하지만이 작동하지 않습니다이 아래 문서에 설명되어 무엇인가 동시에 여러 요청을 보내는 경우 제대로. 동시성 문제로 인해 로그가 여기 저기에 있습니다.

여러분의 도움을 기다리고 있습니다. 미리 감사드립니다 ....

답변

4

여기에 동일한 주제에 대한 내 질문 : http://www.qos.ch/pipermail/logback-user/2009-August/001220.html

: dynamically creating & destroying logging appenders

가 나는 Log4J를 메일 링리스트에, 나는 정확히 같은 일을 논의한다 스레드에서이 후속

Ceci Gulcu (log4j의 발명가)는 좋은 생각이라고 생각하지 않았습니다 ... 대신 Logback을 사용하도록 제안했습니다.

어쨌든 우리는 맞춤 파일 첨부기를 사용하여이 작업을 수행했습니다. 자세한 내용은 위의 토론을 참조하십시오.

+1

@ eqbridges log4j에서 NDC를 사용 했습니까? 내가 log4j API 에서이있어 ... 중첩 된 진단 컨텍스트, 또는 간단히 NDC는 서로 다른 소스에서 인터리브 로그 출력을 구별하는 도구입니다. 서버가 여러 클라이언트를 거의 동시에 처리 할 때 일반적으로 로그 출력이 인터리브됩니다. 다른 컨텍스트의 각 로그 항목에 고유 한 스탬프가 있으면 인터리브 된 로그 출력이 여전히 의미가 있습니다. 이것은 NDC가 작동하는 곳입니다. –

+0

나는 과거에 NDC를 사용했다. 그것은 정말로 당신이하려고하는 것에 대한 적절한 해결책입니다. 요청 당 별도의 로그 파일을 작성하려고하면 발생하는 문제의 표면을 긁어 모으고 있습니다. –

3

log32 (log4j의 후속 버전)와 함께 출하되는 SiftingAppender을 보면 런타임 기준에 따라 appender 생성을 처리하도록 설계되었습니다.

응용 프로그램에서 세션 당 하나의 로그 파일 만 만들어야하는 경우 세션 ID를 기준으로 디스크립터를 작성하기 만하면됩니다. discriminator를 작성하는 것은 3 줄 또는 4 줄의 코드를 포함하므로 상당히 쉬워야합니다. 도움이 필요하면 logback-user 메일 링리스트를 외치십시오.

0

이 문제는 Logback으로 매우 잘 처리됩니다. 자유가 있다면 선택하는 것이 좋습니다.

가능한 경우 가정용은 SiftingAppender입니다. 런타임 값에 따라 로그 파일을 분리 할 수 ​​있습니다. 즉, 로그 파일을 분할하는 방법에 대한 다양한 옵션이 있습니다.

logback :

당신이 뭔가를 할 수 있습니다, requestId에 파일을 분할합니다.당신이 (discriminator 요소 내부를) 볼 수 있듯이 XML

<configuration> 

    <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"> 
    <discriminator> 
     <key>requestId</key> 
     <defaultValue>unknown</defaultValue> 
    </discriminator> 
    <sift> 
     <appender name="FILE-${requestId}" class="ch.qos.logback.core.FileAppender"> 
     <file>${requestId}.log</file> 
     <append>false</append> 
     <layout class="ch.qos.logback.classic.PatternLayout"> 
      <pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern> 
     </layout> 
     </appender> 
    </sift> 
    </appender> 

    <root level="DEBUG"> 
    <appender-ref ref="SIFT" /> 
    </root> 

</configuration> 

, 당신은 requestId에 쓰기 로그에 사용되는 파일을 식별하는 것입니다. 즉, 각 요청은 일치하는 requestId이있는 파일로 이동합니다. 따라서 requestId=1이라는 두 요청이 있고 requestId=2이라는 요청이있는 경우 1.log (2 개 항목) 및 2.log (1 개 항목)의 로그 파일 2 개가 있어야합니다.

이 시점에서 key을 설정하는 방법이 궁금 할 수 있습니다. 이것은 (그 키가 logback.xml 파일에 정의 된 하나와 일치주의) MDC에 키 - 값 쌍을 넣어 수행됩니다

RequestProcessor.java

public class RequestProcessor { 

    private static final Logger log = LoggerFactory.getLogger(RequestProcessor.java); 

    public void process(Request request) { 
     MDC.put("requestId", request.getId()); 
     log.debug("Request received: {}", request); 
    } 
} 

을 그리고 간단한 사용 사례에 대한 기본적입니다. 이제 다른 ID (아직 발견되지 않은)가있는 요청이 들어올 때마다 새로운 파일이 생성 될 것입니다.

관련 문제