2013-07-01 3 views
11

Log4j2도 종료 훅을 사용하여 서비스를 종료합니다. 물론 내 응용 프로그램의 전체 수명 (종료 포함) 동안 로그에 기록하고 싶습니다. Log4j에서는 아무런 문제가 없었습니다. 이제는 불가능한 것 같습니다. 로깅은 내 응용 프로그램이 아직 작업하는 동안 종료됩니다. 누군가 나를 위해 희망을 가지고 있습니까?Log4j2를 사용하여 시스템 종료 후크에 어떻게 로그합니까?

안부 마틴

<configuration ... shutdownHook="disable"> 

의 현재 장애인을 고려할 때, 나는 내가 말에 수동으로 종료 로깅 시스템이 필요 추측 XML 지금 구성 할 수 있습니다 2.0 beta9 기준으로

+0

로깅 또는 종료 훅의 다른 서비스에 따라 계속해서 나쁜 습관이되었습니다. 이제는 따라 잡고 있습니다. –

+0

@MarkoTopolnik 당신이 말한대로 나쁜 습관이라면, 셧다운 훅 스레드의 출력이 기록/기록을 필요로 할 때 무엇을 제안하겠습니까? – vegemite4me

+0

셧다운 훅에서는 초기화 된 상태의 어떤 부분도 여전히 존재한다고 믿을 수 없기 때문에 세미 - 안정적인 것으로 보이는 유일한 것은 파일을 생성하고 그것에 쓰는 완전 독립된 코드 조각입니다. 코어 덤프가 이루어지는 방식과 비슷합니다. –

답변

19

내 종료 후크. 그러나 나는 단지 내부 API를

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.core.config.Configurator; 
import org.apache.logging.log4j.core.LoggerContext; 
... 

public static void main(String[] args) { 
    final AnnotationConfigApplicationContext springContext = new AnnotationConfigApplicationContext(AppConfig.class) 

    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      //shutdown application 
      LOG.info("Shutting down spring context"); 
      springContext.close(); 

      //shutdown log4j2 
      if(LogManager.getContext() instanceof LoggerContext) { 
       logger.info("Shutting down log4j2"); 
       Configurator.shutdown((LoggerContext)LogManager.getContext()); 
      } else 
       logger.warn("Unable to shutdown log4j2"); 
     } 
    }); 

    //more application initialization 
} 
+0

혹시 이것을 알아 냈습니까? – user671731

+1

문제는 자바의 종료 훅이 병렬로 시작된다는 것입니다. 그래서 정말로 모든 곳에서 로그 할 수 있는지 확인하려면 주어진 Runtime.getRuntime(). addShutdownHook (Thread) -API에 후크를 추가하는 것을 피해야 만합니다.하지만 모든 작업이 중단 된 후에 log4j 2.0을 수동으로 중지하는 워크 플로우를 직접 만들면됩니다. 하지만 Log4j가 shutdownHook-trigger를 제공했을 때 주요 문제가 해결되었습니다. – Martin

+0

나만의 워크 플로를 만들어야한다는 데 동의합니다. 나는 일반적으로 리눅스에서 내 응용 프로그램을 실행하고 JVM에 신호를 통해 종료하므로 종료 훅은이 목적에 적합합니다 (코드 스 니펫을 업데이트하여이 컨텍스트를 표시했습니다).간단한 shutdownHookTrigger 레퍼런스를 찾지 못했습니다. 잠시 후 Google에 연결 하시겠습니까? – Chomeh

7

에 철저한 외부 인터페이스를하는 방법을 찾을 수 없습니다 나는 기본적으로 그냥 같은 질문에 대한 답변과 나는 힘든 나는 여기에 내 대답을 공유 할 수 있습니다. complete answer available here을 읽어 보시기 바랍니다. 여기에 요약을 제공하고 현재 상황에 대한 나의 대답을 적용하려고 노력할 것입니다.

첫 번째 버전에서 Log4j는 수동으로 종료 절차를 호출하는 API를 제공하고있었습니다. 우리는 지식이 없기 때문에 it was removed from the second version입니다. 이제, 존재하지 않는 문서에 따르면 올바른 방법은 종료 절차를 담당하는 ShutdownCallbackRegistry 인터페이스의 구현을 제공하는 것입니다.

나는이 문제를 해결하기 위해 무슨 짓 제안 된 솔루션을

나는 ShutdownCallbackRegistry 인터페이스의 내 자신의 버전을 구현한다는 것입니다. 대부분은 디폴트의 구현과 같은 일을 합니다만, JVM에의 슛 다운 훅으로서 등록하는 대신, 수동으로 호출 할 때까지 대기합니다.

GitHub/DjDCH/Log4j-StaticShutdown에서 전체 솔루션과 지침을 찾아보고 자신의 프로젝트에서 사용할 수 있습니다. 기본적으로, 마지막에, 당신은 단지 응용 프로그램에서 같은 것을 할 필요가 :

Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
    @Override 
    public void run() { 
     try { 
      // Do your usual shutdown stuff here that need logging 
     } finally { 
      // Shutdown Log4j 2 manually 
      StaticShutdownCallbackRegistry.invoke(); 
     } 
    } 
})); 

나는 이것이 완벽한 해결책이 있는지 의심의 여지없이 내 구현 완벽이라고 말할 수는 없지만, 내가 시도 그것을 올바른 방법으로 행하는 것. 이 솔루션이 적절하거나 적절하지 않은 경우 귀사의 의견을 듣게되어 기쁩니다.