상태에 대한 JavaDocsjava.util.logging.Level
:
내림차순의 레벨은 다음과 같습니다.
SEVERE
(가장 높은 값)WARNING
INFO
CONFIG
FINE
FINER
FINEST
(가장 낮은 값)
출처
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
logger.setLevel(Level.FINER);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
산출
Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevelsBlunder main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 2 4
Press any key to continue . . .
문제 설명
내 예는 설정 Level
에 FINER
내가 각 루프에 대한이 메시지를 볼 것으로 예상 그래서. 대신 각 루프에 대해 단일 메시지가 표시됩니다 ( Level.FINE
메시지가 없음).
질문
FINE
( FINER
또는 FINEST
) 출력 을 보려면 무엇을 변경해야 합니까?
업데이트 (솔루션)
Vineet Reynolds의 답변 덕분 에이 버전은 내 기대대로 작동합니다. 3 개의 INFO
메시지와 3 개의 메시지를 표시 FINE
합니다.
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
// LOG this level to the log
logger.setLevel(Level.FINER);
ConsoleHandler handler = new ConsoleHandler();
// PUBLISH this level
handler.setLevel(Level.FINER);
logger.addHandler(handler);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
답변
로거는 메시지 만 기록합니다. 즉, 로그 기록 (또는 기록 요청)을 생성합니다. 처리기가 처리하는 대상에 메시지를 게시하지 않습니다. 로거 수준을 설정하면 해당 수준 이상과 일치하는 로그 레코드 만 생성 됩니다.
당신은 ConsoleHandler
(당신의 출력이 System.err 또는 파일 인 곳을 추론 할 수는 없지만 그것이 전자라고 가정합니다)를 사용할 수 있습니다. 이는 기본적으로 수준의 로그 레코드를 게시합니다 Level.INFO
. Level.FINER
원하는 결과를 위해 레벨 이상의 로그 레코드를 게시하려면이 핸들러를 구성해야합니다 .
기본 디자인을 이해하려면 Java 로깅 개요 가이드를 읽는 것이 좋습니다 . 이 가이드는 로거와 핸들러 개념의 차이점을 다룹니다.
핸들러 레벨 편집
1. 구성 파일 사용
java.util.logging 속성 파일 (기본적으로의 logging.properties
파일 JRE_HOME/lib
)을 수정하여 ConsoleHandler의 기본 수준을 변경할 수 있습니다.
java.util.logging.ConsoleHandler.level = FINER
2. 런타임에 핸들러 생성
글로벌 구성을 대체 할 수 있으므로 권장되지 않습니다. 코드베이스 전체에서 이것을 사용하면 관리 할 수없는 로거 구성이 발생할 수 있습니다.
Handler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.FINER);
Logger.getAnonymousLogger().addHandler(consoleHandler);
답변
이유
java.util.logging에는 기본값 인 루트 로거와 기본값 인 Level.INFO
ConsoleHandler가 첨부되어 있습니다 Level.INFO
.
FINE
이보다 낮으므로 INFO
기본적으로 고급 메시지가 표시되지 않습니다.
해결책 1
예를 들어 패키지 이름에서 전체 애플리케이션에 대한 로거를 생성하거나를 사용 Logger.getGlobal()
하고 자체 ConsoleLogger를 여기에 연결합니다. 그런 다음 루트 로거에게 종료를 요청하거나 (상위 메시지의 중복 출력을 방지하기 위해) 로그 를 루트로 전달하지 않도록 로거에 요청하십시오 .
public static final Logger applog = Logger.getGlobal();
...
// Create and set handler
Handler systemOut = new ConsoleHandler();
systemOut.setLevel( Level.ALL );
applog.addHandler( systemOut );
applog.setLevel( Level.ALL );
// Prevent logs from processed by default Console handler.
applog.setUseParentHandlers( false ); // Solution 1
Logger.getLogger("").setLevel( Level.OFF ); // Solution 2
해결 방법 2
또는 루트 로거의 막대를 낮출 수 있습니다.
코드로 설정할 수 있습니다.
Logger rootLog = Logger.getLogger("");
rootLog.setLevel( Level.FINE );
rootLog.getHandlers()[0].setLevel( Level.FINE ); // Default console handler
또는 로깅 구성 파일을 사용하는 경우 :
.level = FINE
java.util.logging.ConsoleHandler.level = FINE
전역 수준을 낮추면 일부 Swing 또는 JavaFX 구성 요소와 같은 핵심 라이브러리의 메시지를 볼 수 있습니다. 이 경우 당신은 설정할 수 있습니다 필터 프로그램에서하지 메시지를 필터링 할 루트 로거에 있습니다.
답변
로그인이 예상대로 작동하지 않는 이유를 파악하는 데 도움이되는 jar 파일을 제공합니다. 어떤 로거와 핸들러가 설치되었는지, 어떤 레벨이 설정되었는지, 로깅 계층 구조에서 어느 레벨에 있는지에 대한 완전한 덤프를 제공합니다.
답변
왜
@Sheepy에서 언급했듯이 작동하지 않는 이유 java.util.logging.Logger
는 기본값 인 루트 로거가 Level.INFO
있고 ConsoleHandler
해당 루트 로거에 첨부 된 파일도 기본값 인 Level.INFO
. 따라서 참조하기 위해 FINE
( FINER
또는 FINEST
) 출력을, 루트 로거의 기본 값을 설정해야하고는 ConsoleHandler
하기 Level.FINE
로 다음과 같습니다 :
Logger.getLogger("").setLevel(Level.FINE);
Logger.getLogger("").getHandlers()[0].setLevel(Level.FINE);
업데이트 문제 (솔루션)
@mins가 언급했듯이 콘솔에 메시지가 두 번 인쇄됩니다 INFO
. 먼저 익명 로거에 의해 다음 상위 로거 가 기본적으로 ConsoleHandler
설정되어 있는 루트 로거 에 INFO
의해 인쇄됩니다. 루트 로거를 비활성화하려면 다음 코드 줄을 추가해야합니다.logger.setUseParentHandlers(false);
@Sheepy가 언급 한 루트 로거의 기본 콘솔 핸들러에서 로그가 처리되는 것을 방지하는 다른 방법이 있습니다. 예 :
Logger.getLogger("").getHandlers()[0].setLevel( Level.OFF );
그러나 Logger.getLogger("").setLevel( Level.OFF );
루트 로거에 직접 전달 된 메시지 만 차단하고 자식 로거에서 온 메시지가 아니므로 작동하지 않습니다. Logger Hierarchy
작동 방식을 설명하기 위해 다음 다이어그램을 그립니다.
public void setLevel(Level newLevel)
이 로거가 기록 할 메시지 수준을 지정하는 로그 수준을 설정합니다. 이 값보다 낮은 메시지 수준은 삭제됩니다. 레벨 값 Level.OFF를 사용하여 로깅을 끌 수 있습니다. 새 수준이 null이면이 노드가 특정 (null이 아닌) 수준 값을 사용하여 가장 가까운 조상으로부터 수준을 상속해야 함을 의미합니다.
답변
내 실제 문제를 발견했지만 어떤 답변에도 언급되지 않았습니다. 일부 단위 테스트로 인해 로깅 초기화 코드가 동일한 테스트 스위트 내에서 여러 번 실행되어 이후 테스트에서 로깅이 엉망이되었습니다.
답변
다른 변형을 시도했습니다. 이것은 적절할 수 있습니다.
Logger logger = Logger.getLogger(MyClass.class.getName());
Level level = Level.ALL;
for(Handler h : java.util.logging.Logger.getLogger("").getHandlers())
h.setLevel(level);
logger.setLevel(level);
// this must be shown
logger.fine("fine");
logger.info("info");
답변
이 솔루션은 유지 관리 및 변경 설계와 관련하여 나에게 더 잘 보입니다.
-
jar 파일에 포함 할 리소스 프로젝트 폴더에 포함하는 로깅 속성 파일을 만듭니다.
# Logging handlers = java.util.logging.ConsoleHandler .level = ALL # Console Logging java.util.logging.ConsoleHandler.level = ALL
-
코드에서 속성 파일을로드합니다.
public static java.net.URL retrieveURLOfJarResource(String resourceName) { return Thread.currentThread().getContextClassLoader().getResource(resourceName); } public synchronized void initializeLogger() { try (InputStream is = retrieveURLOfJarResource("logging.properties").openStream()) { LogManager.getLogManager().readConfiguration(is); } catch (IOException e) { // ... } }