2016-07-18 2 views
1

com.project.callcontrol 패키지의 두 클래스에서 로그를 동일한 파일로 리디렉션하려고합니다. 이것은 내가 클래스 모두에서 개인 정적 최종 로거 로거 = 로거를 시작하는 방법입니다java.util.logging이 두 클래스 사이에서 로거를 공유 할 수 없습니다.

private static Logger log = Logger.getLogger(CCPurgeEvent.class.getName()); 

private static Logger log = Logger.getLogger(PurgeDeadCalls.class.getName()); 

이 내가 구성

을 java.util.logging의 두 클래스에 대해 동일한 파일을 공유하기 위해 노력하고있어 어떻게 내 문제는 내가의 로그 두 클래스에서 얻을 수 없다는 것입니다
com.project.callcontrol.PurgeDeadCalls.useParentHandlers = false 
com.project.callcontrol.PurgeDeadCalls.handlers = com.project.logging.CcPurgeLogger 

com.project.callcontrol.CCPurgeEvent.useParentHandlers = false 
com.project.callcontrol.CCPurgeEvent.handlers = com.project.logging.CcPurgeLogger 

com.project.logging.CcPurgeLogger.pattern=/var/log/voxcallcontrol-batches/cc_purge%u.log 
com.project.logging.CcPurgeLogger.formatter = java.util.logging.SimpleFormatter 
com.project.logging.CcPurgeLogger.level = FINEST 
com.project.logging.CcPurgeLogger.limit=100000000 
com.project.logging.CcPurgeLogger.count=10 

그 CCPurgeLogger 그냥 부모 클래스의 FileHandler의 방법을 만들어, 아무것도하지 않습니다 유의하시기 바랍니다 (거기 왜 알지도 못하는) 로그 파일, 구성 순서에 따라 하나의 클래스에서만 로그를 얻을 수 있습니다. 내 구성 파일에. 예를 들어 PurgeDeadCalls 구성보다 CCPurgeEvent 구성을 이동하면 PurgeDeadCalls이 아닌 CCPurgeEvent에서 작동하고 주문을 전환하면 그 반대가 발생합니다. 내가 누락 된 부분을 이해할 수없는 것 같습니다.이 방향의 포인터는 매우 유용합니다.

P.S : 로깅 프레임 워크를 변경할 수 없습니다. log4j 및 다른 프레임 워크가 더 많은 옵션을 제공한다는 것을 알고 있지만, 현재 작업 범위에서는 java.util.logging 만 사용해야합니다.

답변

1

두 개의 로거에 대해 하나의 로그 파일을 공유하려면 일반적인 상위 로거에 핸들러를 설치해야하며 코드는 상위 로거를 가져 와서 메모리에 고정해야합니다. 첫 번째 공통 상위는 com.project.callcontrol입니다.

com.project.callcontrol.handlers = com.project.logging.CcPurgeLogger 
com.project.callcontrol.PurgeDeadCalls.useParentHandlers = true 
com.project.callcontrol.CCPurgeEvent.useParentHandlers = true 

com.project.logging.CcPurgeLogger.pattern=/var/log/voxcallcontrol-batches/cc_purge%u.log 
com.project.logging.CcPurgeLogger.formatter = java.util.logging.SimpleFormatter 
com.project.logging.CcPurgeLogger.level = FINEST 
com.project.logging.CcPurgeLogger.limit=100000000 
com.project.logging.CcPurgeLogger.count=10 

당신이 뭔가에 com.project.logging.CcPurgeLogger 핸들러의 구현을 변경하려면 기존 구성을 다음 한 사용하려는 경우 :

public class CcPurgeLogger extends Handler { 

    private static volatile Handler common; 
    private static long count; 


    private static void create() throws IOException { 
     synchronized (CcPurgeLogger.class) { 
      if (common == null) { 
       common = new FileHandler(); 
      } 
      count++; 
     } 
    } 

    public CcPurgeLogger() throws IOException { 
     create(); 
    } 

    @Override 
    public boolean isLoggable(LogRecord record) { 
     String name = record.getLoggerName(); 
     return ("com.project.callcontrol.PurgeDeadCalls".equals(name) 
       || "com.project.callcontrol.CCPurgeEvent".equals(name)) 
       && common.isLoggable(record); 
    } 

    @Override 
    public void publish(LogRecord record) { 
     common.publish(record); 
    } 

    @Override 
    public void flush() { 
     common.flush(); 
    } 

    @Override 
    public void close() throws SecurityException { 
     synchronized (CcPurgeLogger.class) { 
      if (common != null) { 
       if (count == 1L) { 
        common.close(); 
        common = null; 
       } 
       --count; 
      } 
     } 
    } 
} 

당신은 또한 새로운 서브 시스템을 정의하는 예를 공유 할 수 구성 파일의 로거?

서브 시스템의 이름을 그대로 사용하십시오 (일부 클래스 이름).

com.project.callcontrol.PURGE.handlers = com.project.logging.CcPurgeLogger 
com.project.callcontrol.PURGE.useParentHandlers = true 


com.project.logging.CcPurgeLogger.pattern=/var/log/voxcallcontrol-batches/cc_purge%u.log 
com.project.logging.CcPurgeLogger.formatter = java.util.logging.SimpleFormatter 
com.project.logging.CcPurgeLogger.level = FINEST 
com.project.logging.CcPurgeLogger.limit=100000000 
com.project.logging.CcPurgeLogger.count=10 

그런 다음 'PurgeDeadCalls'클래스와 'CCPurgeEvent'클래스 모두의 안에 다음을 수행하여 서브 시스템의 로거를 가져옵니다.

private static Logger log = Logger.getLogger("com.project.callcontrol.PURGE"); 
+0

안녕 @jmerherns, 당신은 제안 된 구성 솔루션에서 패키지 'com.project.callcontrol'에서 다른 클래스의 로그도 요구되지 않은 동일한 파일에 로깅을 시작합니다. 이 두 클래스의 모든 로그를 하나의 로그 파일에 저장했습니다. CCPurgeEvent는 PurgeDeadCalls에서만 사용되기 때문에 내가 할 수있는 또 다른 일은 PurgeDeadcalls에서 'Logger'를 CCPurgeEvent로 전달하는 것입니다. 'log4j'를 사용하는 경우 동일한 문제가 발생하는지 궁금합니다. – Nitesh

+0

@ Nitesh 사용자 지정 처리기를 만들었으므로 로거 이름을 확인하고 설치하는 사용자 지정 필터를 만들 수도 있습니다. 아니면 그냥 필터링을 할 사용자 지정 처리기의 isLoggable 메서드를 재정의하십시오. 설정을 고수하고 싶다면보고 싶지 않은 모든 로거에 대해'.useParentHandlers'를 꺼야합니다. – jmehrens

+0

고마워요.하지만 정말 실망 스럽습니다. 두 클래스에서 같은 로거를 사용하는 것이 왜 그렇게 복잡한 지 이해할 수 없습니다. Custur Logger CCPurgeLogger를 수정하고 싶지 않고이 패키지의 다른 모든 클래스가 루트 로거에 쓰므로 모든 클래스에 대해 'useParentLogger'를 비활성화 할 수 없으며 50 개의 클래스가 있습니다. 그들 모두를 수정하고 싶지 않다. 다른 옵션이 없으면 log4j로 해결하기가 더 쉬울까요 ?? – Nitesh