2014-06-10 8 views
1

Logback Logger의 래퍼로 작동하는 클래스를 작성하고 있습니다. 특히 감사 로깅을 용이하게하는 것입니다. 사람들이 가져 와서 사용할 수 있어야하는 독립적 인 라이브러리 여야합니다. 내가 가진 문제는 프로그램 적으로 LogBack을 선언하는 데 필요한 최소한의 문서화와 관련이 있습니다. 다른 스택 오버플로 질문 (Setting Logback Appender path programmatically)에 대한 일반 선언을 기반으로합니다.Logback 감사 로거 래퍼 만들기

현재 정의한 내용은 다음과 같습니다. 현재 마커 필터가 작동하는 데 문제가 있습니다. 그것은 마커 필터처럼, 내가 선언 한 것처럼 아무것도하지 않는다. 궁극적으로 감사 로깅을 제외하고 다른 정보가 감사 로그 파일에 기록되지 않도록해야합니다. 그것이 내가 불일치에 대해 거부하는 이유입니다. 내 테스트에서 그것은 단지 무시된다는 것으로 보인다.

프로그래밍 방식으로 생성 된 Logback 파일에 관한 모든 정보 또는 지침이 많은 도움이 될 것입니다. 또한 사용자가 내 클래스를 사용하여 감사 로깅을 수행 한 다음 Logback.xml이 자체로 별도의 로깅을 수행 할 때 걱정해야 할 사항이 있습니까? 당신이

import ch.qos.logback.classic.Level; 
import ch.qos.logback.core.spi.FilterReply; 
import org.slf4j.LoggerFactory; 
import org.slf4j.Marker; 
import org.slf4j.MarkerFactory; 
import ch.qos.logback.classic.Logger; 
import ch.qos.logback.classic.LoggerContext; 
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; 
import ch.qos.logback.core.rolling.TimeBasedRollingPolicy; 
import ch.qos.logback.core.rolling.RollingFileAppender; 
import ch.qos.logback.core.filter.EvaluatorFilter; 
import ch.qos.logback.classic.boolex.OnMarkerEvaluator; 


public class AuditLogger { 
    private static Logger logbackLogger; 
    final static Marker AUDIT = MarkerFactory.getMarker("AUDIT"); 

    static { 
     LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); 

     RollingFileAppender rfAppender = new RollingFileAppender(); 
     rfAppender.setContext(loggerContext); 
     rfAppender.setFile("auditLogFile.currentDay.log"); 
     TimeBasedRollingPolicy rollingPolicy = new TimeBasedRollingPolicy(); 
     rollingPolicy.setContext(loggerContext); 
     // rolling policies need to know their parent 
     // it's one of the rare cases, where a sub-component knows about its parent 
     rollingPolicy.setParent(rfAppender); 
     rollingPolicy.setFileNamePattern("auditLogFile.%d{yyyy-MM-dd}.log"); 
     rollingPolicy.start(); 

     PatternLayoutEncoder encoder = new PatternLayoutEncoder(); 
     encoder.setContext(loggerContext); 
     encoder.setPattern("[%d{ISO8601}] %5marker - %msg%n"); 
     encoder.start(); 

     rfAppender.setEncoder(encoder); 
     rfAppender.setRollingPolicy(rollingPolicy); 
     rfAppender.start(); 

     EvaluatorFilter evalFilter= new EvaluatorFilter(); 
     OnMarkerEvaluator markerEval= new OnMarkerEvaluator(); 
     markerEval.addMarker("AUDIT"); 

     evalFilter.setEvaluator(markerEval); 
     evalFilter.setOnMatch(FilterReply.ACCEPT); 
     evalFilter.setOnMismatch(FilterReply.DENY); 

     rfAppender.addFilter(evalFilter); 

     logbackLogger = loggerContext.getLogger("AUDIT_LOGGER"); 
     logbackLogger.addAppender(rfAppender); 

     logbackLogger.setLevel(Level.DEBUG); 

    } 
    public AuditLogger(){} 

    public void log(String msg){ 
     logbackLogger.debug(AUDIT, msg); 
    } 
} 
+0

그래서 저는 EvaluatorFilter와 OnMarkerEvaluator를 "start()"해야한다고 알았습니다. 이 두 문장 ("evalFilter.start()"및 "markerEval.start()")을 넣으면 필터가 작동합니다. 프로그래밍 방식으로 생성 된 로그백 구성과 기본 xml 둘 다 상호 작용하는 방법에 대한 자세한 정보를 찾고 있습니다. – JDP10101

답변

0

내가 프로그래밍 생성 Logback 파일에 대한 정보를 훨씬 못 찾았하지만 난 내 테스트와 주변 하구에서 발견 한 일을 공유 할 감사합니다.

먼저 링크 된 게시물에서 Ceki의 응답을 적용하기 위해 logback.xml 예제와 온라인 API를 조합하여 사용했습니다. 예를 들어, 마커 필터를 수행하는 방법을 찾으려면 XML에 "ch.qos.logback.core.filter.EvaluatorFilter"및 "ch.qos.logback.classic.boolex.OnMarkerEvaluator"클래스에 대한 링크가 있음을 발견했습니다. ". 여기에있는 API를 사용했습니다 : http://logback.qos.ch/apidocs/ch/qos/logback/core/filter/EvaluatorFilter.html. 프로그래밍 방식으로 로그백 인스턴스를 초기화 할 때 작성하는 모든 필터, appender, 인코더, 롤링 정책, 평가 기 및 기타 항목에 대해 start() 메서드를 실행하는 것을 기억하십시오 (위의 설명대로). 그렇지 않으면 작동하지 않습니다.

프로그래밍 방식으로 작성된 xml 로그백 인스턴스의 여러 조합을 사용한 테스트에서 흥미로운 결과가 나타납니다. 프로그래밍 방식으로 생성 된 logback 인스턴스와 xml로 만든 인스턴스가 함께 작동하는 것처럼 보입니다. 예를 들어, 프로그래밍 방식으로 생성 된 인스턴스에서 logger.debug ("msg")를 호출하면 "msg"도 XML 생성 인스턴스에 의해 수신되고 평가됩니다. 나는 그들이 모두 같은 "루트"로거를 공유하기 때문이라고 생각한다.

사용자가 로그백을 사용하지 않고 콘솔에 출력하지 않을 때 라이브러리가 올바르게 작동하려면 다음 코드를 사용하십시오. 기본 로거가 존재하는지 확인하고 존재할 경우 콘솔로 퍼를 제거합니다. 사용자 프로그램은 log4j를 사용하고 "SLF4J-log4j12"라는 클래스를 가져올 때

if (loggerContext.getLoggerList().size() == 1) { 
     Logger root= loggerContext.getLogger("ROOT"); 
     root.detachAppender("console"); 
    } 

내가 찾은 유일한 치명적인 오류

이었다. 이 프로그램은 slf4j의 여러 인스턴스에 대해 불평했고 사망했습니다. "slf4j-log4j12"메이븐 라이브러리를 프로젝트에서 제거함으로써 잘 작동했습니다.