2011-11-03 1 views

답변

10

이 작업은 Log4J의 후속 버전 인 Logback에서 수행 할 수 있습니다.

Log4j가 떠나는 인기있는 log4j 프로젝트의 후계자로서 Logback이 후발되었습니다.

는 SiftingAppender가 참조하고 중첩 된 펜더을 구성하는 능력에서 고유 Sifting Appender

설명서를 참조하십시오. 위의 예에서 SiftingAppender 내에는 중첩 된 FileAppender 인스턴스가 있으며 각 인스턴스는 "userid"MDC 키와 연관된 값으로 식별됩니다. "userid"MDC 키에 새 값이 할당 될 때마다 새로운 FileAppender 인스턴스가 처음부터 빌드됩니다. SiftingAppender는 자신이 만든 appender를 추적합니다. 30 분 동안 사용되지 않은 애펜더는 자동으로 닫히고 버려집니다.

예에서 MDC 값을 기반으로 각 사용자에 대해 별도의 로그 파일을 생성합니다. 필요에 따라 다른 MDC 값을 사용할 수 있습니다.

+0

Logback을 사용하면 모든 로깅 구문을 바꿔야한다는 의미일까요? –

+1

http://slf4j.org/legacy.html에서 기존 API 브리징을 참조하십시오. – Ceki

9

이는 log4j에서도 가능합니다. 자신의 appender를 구현하여이를 수행 할 수 있습니다. 가장 쉬운 방법은 서브 클래스 AppenderSkeleton입니다.

모든 로깅 이벤트는 구현해야하는 append(LoggingEvent event) 방법으로 끝납니다. 그 방법 당신이 그런 다음에 쓸 파일을 열려면이 정보를 사용할 수 event.getMDC("nameOfTheKeyToLookFor");

하여 MDC에 액세스 할 수 있습니다에서

. 나머지를 파악하려면 RollingFileAppender과 같은 표준 어 펜더의 구현을 살펴 보는 것이 도움이 될 수 있습니다.

다른 스레드의 로그를 다른 로그 파일로 분리하기 위해이 접근 방식을 응용 프로그램에서 직접 사용했으며 매우 잘 작동했습니다.

+0

RollingFileAppender를 사용하지 않습니다. FileAppender에서 가능합니까? –

+0

RolenderfileAppender는 appender를 구현하는 방법의 예로서 만 언급했습니다.기본적으로 append 메서드에서 원하는대로 할 수 있습니다. – Wolfgang

5

log4j에서 SiftingAppender와 유사한 기능을 찾기 위해 잠시 고생했습니다 (일부 종속성으로 인해 logback으로 전환 할 수 없음). MDC를 사용하고 로거를 추가하는 프로그래밍 방식의 솔루션으로 끝났습니다. 런타임 :

// this can be any thread-specific string 
String processID = request.getProcessID(); 

Logger logger = Logger.getRootLogger(); 

// append a new file logger if no logger exists for this tag 
if(logger.getAppender(processID) == null){ 

    try{ 
    String pattern = "%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n"; 
    String logfile = "log/"+processID+".log"; 

    FileAppender fileAppender = new FileAppender(
     new PatternLayout(pattern), logfile, true); 
    fileAppender.setName(processID); 

    // add a filter so we can ignore any logs from other threads 
    fileAppender.addFilter(new ProcessIDFilter(processID)); 

    logger.addAppender(fileAppender); 
    }catch(Exception e){ 
    throw new RuntimeException(e); 
    } 
} 

// tag all child threads with this process-id so we can separate out log output 
MDC.put("process-id", processID); 

//whatever you want to do in the thread 
LOG.info("This message will only end up in "+processID+".log!"); 

MDC.remove("process-id"); 

바로 위에 추가 된 필터는 특정의 프로세스 ID를 확인 :

public class RunIdFilter extends Filter { 

    private final String runId; 

    public RunIdFilter(String runId) { 
    this.runId = runId; 
    } 

    @Override 
    public int decide(LoggingEvent event) { 
    Object mdc = event.getMDC("run-id"); 

    if (runId.equals(mdc)) { 
     return Filter.ACCEPT; 
    } 

    return Filter.DENY; 
    } 
} 

희망이 조금 돕는다.

+0

Log4j 2에 같은 필터를 쓰려면 어떻게해야합니까? –

+0

첫 번째 블록에 코드를 추가 할 위치는 어디입니까? – NaiveCoder

+0

@NaiveCoder 어디서나 MDC 필터링을 시작하고 싶습니다. – bpodgursky

관련 문제