2017-03-09 6 views
2

오래된 자바 프로젝트를 인계 받았다. 그리고 원래 디자이너가 사라졌습니다. 이 프로젝트에서 , 그것은 다음과 같이 정적 인 방식의 log4j를 사용레벨 당 Log4j2에서 로거를 만들 수 있습니까?

public class LogUtil { 
private static final String FQCN = LogUtil.class.getName(); 
private static final Logger logger1 = Logger.getLogger("INFO"); 
private static final Logger logger2 = Logger.getLogger("ERROR"); 

public static void info(Object message) { 
    if (logger1.isInfoEnabled()) { 
     forcedLog(logger1, Level.INFO, message); 
    } 
} 


public static void error(Object message) { 
    forcedLog(logger2, Level.ERROR, message); 
} 


private static void forcedLog(Logger logger, Level level, Object message) { 
    logger.callAppenders(new LoggingEvent(FQCN, logger, level, message, null)); 
} 

}

그런 다음 다른 클래스는 쉽게 LogUtil.error("")LogUtil.info("")에 로그를 기록 할 수 있습니다. INFO 로거와 ERROR 로거는 별도의 파일로 작성되었습니다.

하지만 Log4j2에서 LoggingEvent 클래스를 찾을 수 없습니다.

Log4j2를 사용하려면이 클래스를 어떻게 수정해야합니까? (아마도 log4j 패키지에 제공된 Log4j 1.x 브리지를 사용 하시겠습니까?)

이런 식으로 로거를 사용하는 것이 합리적입니까? 그것은 클래스 당 로거를 만드는 것보다 쉽습니다 보인다. 성능이나 다른 문제가 있습니까?

답변

1

그래서 Log4j2를 사용하려면이 클래스를 어떻게 수정해야합니까? (어쩌면 log4j2 패키지로 제공 Log4j의 1.x에서 브리지를 사용?)

당신 대신 기본이되는 구현의 세부 사항에 의존의 공개 API를 사용하여 다시 작성합니다. 그래서,이 같은 일이 :

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 

public class LogUtil { 
    private static final Logger TRACE_LOGGER = LogManager.getLogger("TRACE"); 
    private static final Logger DEBUG_LOGGER = LogManager.getLogger("DEBUG"); 
    private static final Logger INFO_LOGGER = LogManager.getLogger("INFO"); 
    private static final Logger WARN_LOGGER = LogManager.getLogger("WARN"); 
    private static final Logger ERROR_LOGGER = LogManager.getLogger("ERROR"); 
    private static final Logger FATAL_LOGGER = LogManager.getLogger("FATAL"); 

    public static void trace(Object msg){ 
     TRACE_LOGGER.trace(msg); 
    } 

    public static void debug(Object msg){ 
     DEBUG_LOGGER.debug(msg); 
    } 

    public static void info(Object msg) { 
     INFO_LOGGER.info(msg); 
    } 

    public static void warn(Object msg){ 
     WARN_LOGGER.warn(msg); 
    } 

    public static void error(Object msg) { 
     ERROR_LOGGER.error(msg); 
    } 

    public static void fatal(Object msg){ 
     FATAL_LOGGER.fatal(msg); 
    } 
    ... 
} 

합리적인 이런 식으로 로거를 사용? 그것은 클래스 당 로거를 만드는 것보다 쉽습니다 보인다. 성능이나 다른 문제가 있습니까?

클래스에 3 줄을 추가하는 것이 쉬운 것 외에는 어떻게 보이지 않습니다. 당신의 log4j의 기능을 많이 제공이 구현으로, 잠재적 인 문제에 관해서는

import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
... 
private static final Logger logger = LogManager.getLogger(); 

: 그것은 (log4j2에서) 로거를 작성하는 데 걸리는 모든이입니다.

  1. 모든 클래스가 동일한 로거를 공유하므로 패키지 또는 클래스 단위로 로그 수준을 변경할 수 없습니다. 아마도 당신이 작업하고있는 새로운 클래스에 대해 TRACE 로깅을 켜기를 원할 것입니다. 그러나 당신은 로그 파일을 혼란스럽게 만들면서 다른 클래스로부터의 어떤 TRACE 로그도 원하지 않습니다. 당신은 쉽게 이런 종류의 변경을 할 수 없을 것입니다.
  2. 다시 한 번 모든 클래스가 동일한 로거를 공유하므로 패키지 또는 클래스 단위로 appender를 변경할 수 없습니다. 아마도 작업중인 새 패키지의 모든 로그를 별도의 파일로 보내서 수동으로 로그를 필터링하지 않고도 새 코드가하는 일을보다 쉽게 ​​확인할 수 있습니다. 어쩌면 특정 클래스 또는 패키지의 모든 로그를 개발 중에 단일 파일로보고 싶어하므로 다른 파일로 이동하지 않고도 쉽게 실행을 수행 할 수 있습니다.
+0

답장을 보내 주셔서 감사합니다. 당신이 말했던 것처럼, 클래스 당 하나의 로거는 몇몇 클래스에 의해 인쇄 된 로그를보다 유연하게 제어 할 수 있습니다. – Tidus

+0

첫 번째 방법을 시도했지만 로그 추적은 모두 비슷했습니다. 'LogUtil.info (LogUtil.java:23) test' 실제 장소 LogUtil.정보가 로그에 인쇄되지 않았습니다. 로그의 실제 위치를 기록하려면 logger.info()를 직접 호출해야합니다. 나는 로거를 작성하려고 생각했다. 'logger = LogManager.getLogger (ClassA.class); ' 클래스'name '을 가진 모든 클래스에 구현하는 데 약간의 시간이 걸릴 수있다. 나는 길을 찾고 LogUtil.info()를 logger.info()로 바꿀 것이다. 감사합니다. . – Tidus

+0

로거 선언에서 클래스 이름을 사용하는 것과 관련하여 어떤 의미인지 알 수 있습니다. log4j2는 제로 파라미터를 취하는'getLogger()'메소드를 제공한다. [log4j2 API 문서] (https://logging.apache.org/log4j/2.x/manual/api.html) - "로거 이름"에 대한 마지막 절 참조 –