2016-11-09 2 views
3

나는 스프링 부트에서 child() 컨텍스트를 동적으로 만들고 각 컨텍스트를 구분 된 파일에 기록하려고합니다. 이것이 가능한가?Spring 부트 하위() 컨텍스트에 의한 로그백 분리

이유는 다른 어댑터에 대한 동적 스프링 통합 구성이 있기 때문입니다. 이것은 동일한 어댑터 구성으로 다른 연결로 작업하는 데 매우 유용하지만 하나의 로그 파일에 대한 많은 정보가 있습니다.

JNDI 컨텍스트 분리에서도 스레드 분리를 보았지만이 작업을 수행하는 가장 좋은 방법은 무엇인지 모르겠습니다. logback.xml 파일을 구성하는 것만 가능합니까?

업데이트 :

아마 옵션이 MDC 내가이 개념을 이해하고 있지 않다. 다른와 @Component에도 적용 할 수

@MessageEndpoint 
public class TestComponents { 

private static final Logger LOGGER = LoggerFactory.getLogger(Test.class); 

@Router(inputChannel = "inputRouter") 
public MessageChannel router(Message<String> demo) { 
.. 
LOGGER.trace(“TEST”); 
… 
LOGGER.error(“TEST”); 
… 
} 

@ServiceActivator(inputChannel="inputService") 
public void service(Message<String> demo) { 
.. 
LOGGER.trace(“TEST”); 
.. 
} 

@Transformer(inputChannel="inputTransformer", outputChannel="outputTransformer") 
public byte[] transformerToByte(Message<String> demo) { 
.. 
LOGGER.debug(“TEST”); 
.. 
} 
} 

예 : 예를 들어, 당신은 다음과 같은 @Transformer, @ServiceActivator@Router 여러 봄의 통합 요소와 봄 @MessageEndpoint 요소에 대한 MDC를 적용하는 방법을 설명 할 수 행동 양식. 내가

인해 문서에 설명 된 paragraph의 성능에 대해 걱정 :

MDC logback-고전 값은 중간 주파수로 MDC에 배치되어 있다고 가정에서 구현 있습니다

답변

0

쉽게 해결할 수 있다고 생각하지 않습니다. Logback에 대한 많은 경험이 없지만 Log4J, Spring, Tomcat 및 클래스 로딩에 대해 잘 알고 있습니다.

log4J는 logton과 같이 정적 팩토리 메소드를 사용하여 단일 로거를 생성하므로 정적 상태가 클래스 로더에 저장된다는 의미입니다. 봄에는 컨텍스트를로드하는 데 사용되는 클래스로드를 지정할 수 있지만 클래스 로더는 상위 클래스 로더가로드 할 수없는 클래스/리소스 만로드합니다 (URLClassLoader.getResource를 재정의하면이를 알 수 있습니다) . 이는 Spring 부트가 시작될 때 로깅이 '루트'클래스 로더에 의해 초기화되고로드되기 때문에 문제가됩니다.

이 문제를 방지하는 유일한 방법은 classpath에서 logback jar를 제거하고 루트 Spring 컨텍스트 및 다른 클래스로드를로드하기위한 새로운 URL 클래스 로더 (로그백 jar 및 구성 만 포함)를 작성하는 것입니다. 자식 문맥을로드한다 (같은 JAR 다른 설정). logback jar는 시스템 클래스 경로의 일부가 아니므로 클래스 로더에 의해 정적 범위가 지정되므로 두 가지 별도의 로그백 구성을 가질 수 있어야합니다.

편집

다이빙 좀 더 깊이 나는 인해 LoggingSystem 클래스가 초기화되는 방식으로, logback 코어와 logback 클래식 항아리를로드하는 클래스 로더를 가지고하는 것만으로는 충분하지 않습니다 것으로 나타났습니다 (LogSystem 라인 126, 버전 1.4.1), 전체 스프링 부트 jar (그리고 잠재적으로 모든 다른 것들)는 같은 클래스 로더에 의해로드 될 필요가 있습니다. 즉, 스프링 부트 응용 프로그램을 실행하는 데 일반적으로 사용되는 jar 번들을 사용할 수 없음을 의미합니다.

+0

감사합니다. 클라우스입니다. 우리의 커스텀 설정이 스프링 부트 설정을 오버라이드하기 때문에이 접근법을 사용할 수는 없지만 스프링 부트는 여전히 child() 컨텍스트가 생성되기 전과 후에 로그백을 사용하고 있습니다. 나는 스프링 확장을 사용하여 프로그램 적으로 설정을 커스터마이징하고있다. – crm86

0

logback에서 MDC (Mapped Diagnostic Context)SiftingAppender과 함께 사용할 수 있습니다. 나는 아래

가 작동하는 방법을 설명 할 것이다 :

  1. MDC 당신은 그것의 값을 기준으로 로그 파일을 분리하는 데 사용할 수있는 판별을 할 수 있습니다. 이 단계에서 하위 컨텍스트의 최상위 스택 메서드를 실행하기 전에 MDC.put('child-context-key', 'childContextId')을 수행하고 실행 후 MDC.remove('child-context-key')을 수행해야합니다.
  2. 그런 다음 ch.qos.logback.classic.sift.SiftingAppender을 구성하여 'child-context-key' 값을 식별자로 사용하여 로그 파일을 분리 할 수 ​​있습니다. 예 :

    <appender name="CHILD-CONTEXT-SIFT-APPENDER" class="ch.qos.logback.classic.sift.SiftingAppender"> 
    <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator"> 
        <key>child-context-key</key> 
        <defaultValue>defaultChildContextId</defaultValue> 
    </discriminator> 
    <sift> 
        <appender name="CHILD-CONTEXT-SIFT-FILE-APPENDER" 
         class="ch.qos.logback.core.rolling.RollingFileAppender"> 
         <file>/path/to/your/log/file/${child-context-key}.log 
         </file> 
    </sift> 
    </appender> 
    

은 또한 당신은 JNDI 판별에 기반 웹 애플리케이션 모듈에 대해 별도의 로그 파일을 구성하는 방법을 보여줍니다 this example 형태 logback을 따를 수 있습니다.

+0

그는 각각의 자식 컨텍스트가 자신의 파일에 로그인하기를 원한다고 생각한다. 따라서 X 번호의 ShiftAppenders, child-1, child-2, child를 정의해야한다. -3 ... child-X. ShiftAppender를 프로그래밍 방식으로 로그백에 추가 할 수 없다면 말입니다. 스프링 컨텍스트를로드하기 전에 MDC를 설정해야하지만 컨텍스트에서 모든 Executor를 사용하는 경우 Executor 스레드에서 설정할 수 있도록 Spring로드 스레드에서 MDC (MDC.getCopyOfContextMap())를 저장해야합니다 즉, ThreadFactory를 정의하거나 각 실행 가능 run 메소드에서 MDC.setContextMap (saved-MDC)를 호출해야합니다. –

+0

@Klaus Groenbaek, 죄송하지만 몇 가지 'SiftAppenders'에 대해 틀 렸습니다. –

+0

Sergey 감사합니다. 나는 설명서를 읽고 있었지만 MDC와 JNDI는 응용 프로그램 서버가 없기 때문에 유효한 옵션이 아니며 MDC는 실제로 성능이 좋지 않습니다. 또한 동적 컨텍스트로 동적으로 구성 가능한 항목을 찾고 있기 때문에 MDC가있는 솔루션이 유효하지 않습니다. MDC는 메시지 나 스레드 분리가 거의 없지만 수십 개의 LOG 추적으로 인해 하위 컨텍스트가 상당히 큰 경우에 유용합니다. – crm86

관련 문제