private static final String CLAZZ_NAME = MyClass.class.getName(); private static final String PKG = MyClass.class.getPackage().getName(); private static Logger _logger = Logger.getLogger(PKG);
MyClass에 대해 사용자의 클래스 이름으로 대체하고 패키지의 리프 노드와 같은 이름을 가지고 있는 특성 파일이 있는지 확인하십시오.
java.util.logging.LogManager.getLogger(String name)는 일치하는 이름을 가지고 있는 로거(이미 존재하는 경우)를 리턴합니다. 그렇지 않으면 널(null)을 리턴합니다. 사용자 클래스의 인스턴스가 생성될 때 제공된 로거가 존재할 것이라는 보장이 없습니다. 클래스 인스턴스화 순서가 판별되지 않기 때문입니다. 현재 존재해도 나중에 순서를 변경할 수 있습니다. 따라서 Logger가 리턴되도록 하려면 Logger 클래스에서 get 메소드를 사용해야 합니다. 로거(logger)를 가져오기 위해 LogManager 또는 Logger를 사용하는지 관계없이, 이름 지정된 로거의 하나 이하의 인스턴스가 지정된 시간에 VM 내에 존재합니다.
com.ibm.rcp.mypackage.level=FINEST
rcpinstall.properties의 기본값을 SEVERE로 변경하여 다른 JSR47 로거(logger)에서 SEVERE 레벨 메시지만 수신할 수 있습니다.
Lotus® Expeditor의 OSGi 콘솔 기능을 사용하여 로깅 레벨을 동적으로 수정할 수도 있습니다. 이 작업을 수행하려면 –console을 실행에 추가하고 여기 설명된 대로 setlogrlev 및 getlogrlev 명령을 사용하십시오.
osgi> setlogrlev com.ibm.rcp.core.internal.pd.manager
시스템 로그는 <workspace>\logs\error-log-0.xml에 있습니다. 여기서 n은 숫자 0(현재 로그) 또는 1(마지막으로 실행된 로그)입니다.
시스템 추적 파일은 <workspace>\logs\trace-log-0.xml에 있습니다. 여기서 n은 숫자 0(현재 로그) 또는 1(마지막으로 실행된 로그)입니다.
로그 및 추적 파일에 대한 자세한 정보는 InfoCenter의 Lotus Expeditor 문제점 해결 지원 절의 클라이언트 데스크탑 문제점 해결 절을 참조하십시오.
if(_logger.isLoggable(WARNING)){
_logger.logp(WARNING,CLAZZ_NAME, METHOD,
Nls.bind("warn.unable.to.get.preference",
new Object[]{pid,key}));
}
private boolean methodP(String param1, String param2) {
logger.entering(CLAZZ_NAME,METHOD, param1 + "," + param2);
}
| 예제 | 보호 필요 여부 | 이유 |
|---|---|---|
| _logger.logp( Level.SEVERE, CLAZZ_NAME, METHOD, NLS.bind( Messages.MessageKey, new Object[] { element[i].getContributor().getName() } ), exception ); | 아니오 | SEVERE 메시지는 항상 로깅됨 |
| _logger.logp( Level.WARNING, CLAZZ_NAME, METHOD, Messages.MessageKey2 ); | 아니오 | 경고 메시지에 로깅하는 단순 호출 |
| _logger.logp( Level.INFO, CLAZZ_NAME, METHOD, NLS.bind( Messages.MessageKey, new Object[] { element[i].getContributor().getName(), createReportFromExtension( element[i] ) }, exception ) | 예 | createReportFromExtension이 메시지에서 바꿀 오브젝트를 생성하는 중요한 작업을 수행해야 합니다. |
| _logger.entering( CLAZZ_NAME, METHOD ) | 아니오 | _logger.entering는 레벨 검사를 수행하므로 코드 읽기가 쉬워집니다. |
String result = "something" ... _logger.exiting( CLAZZ_NAME, METHOD, result ) |
아니오 | _logger.exiting는 레벨 검사를 수행하므로 코드 읽기가 쉬워집니다. |
... _logger.exiting( CLAZZ_NAME, METHOD, result ) |
아니오 | 로깅 레벨을 사용하지 않으면 결과 오브젝트가 문자열로 변환되지 않습니다. |
SomeObject result = getFromSomeplace(); ... _logger.exiting( CLAZZ_NAME, METHOD, result.toString() ) |
예 | toString() 오퍼레이션은
기존 메소드를 호출하기 전에 해결해야 하는 큰 문자열을 작성하므로 광범위한 문자열
오퍼레이션을 방지하도록 보호받는 검사를 수행하십시오. 주: 매개변수에
toString() 메소드가 포함되지 않은 경우, 결과가 exiting() 서명과 일치하며
java.util.loggin이 제공하는 내장된 보호로 진행하므로 이 호출은 보호가
필요하지 않습니다.
|
INFO
Done with install operations
수행 금지: 디버그 정보나 프로그램 실행 추적에 대해, 잠재적으로 자주 반복되는 이벤트에서, 또는 관련된 이벤트의 문제점 원인을 판별할 때 유용하지 않을 경우 단지 이벤트를 확인하기 위해 INFO를 사용하지 마십시오.
WARNING
Failed to retrieve page file for URL EXPEDITOR.png.
수행 금지: 문제점으로 인해 기능을 완전히 또는 심각하게 사용할 수 없거나, 약화된 기능을 표시하지 않는 정보 메시지에 대해 WARNING을 사용하지 마십시오.
SEVERE
Error loading plugin customization file
수행 금지: 모든 기능 또는 대부분의 기능이 계속 사용 가능하거나 문제점이 일시적인 경우 SEVERE를 사용하지 마십시오.
기본적으로 추적은 사용하지 않습니다. 추적은 개발자, 품질 엔지니어 및 지원 부서 요원이 사용하기 위한 것입니다.
세 가지의 추적 레벨(FINE, FINER 및 FINEST)이 있습니다.
FINE: 문제점을 이해하거나 디버그하려고 할 때 시스템 플로우 또는 상태를 설명하는 중요한 이벤트에 대해서는 이 레벨을 사용하십시오. 이는 보통 오브젝트 작성 레벨, 오류를 생성하지 않는 예외에 대한 catch 절 등에 있습니다.
FINEST: Finest는 보통 개발자 또는 디버그 추적처럼 생각합니다. 이는 개발하는 동안 Fine 레벨의 세부사항으로 시스템 동작을 학습하려고 할 때, 그리고 코드가 릴리스될 때 어려운 문제점을 진단하려고 할 때 사용됩니다.
추적은 개발 중 및 개발 후에 가치있는 도구입니다. 추적은 동적 사용을 지원해야 하며 java.util.logging.Logger API를 사용하여 완료되어야 합니다. 경험에 의하면, 개발 중에 가치가 있으면 나중에도 가치가 있습니다. println 또는 printStackTrace는 동적 사용 또는 레벨 관리를 지원하지 않고 대부분의 경우 문제점 판별용으로 시스템 추적 파일 사용을 시도하여 혼란을 초래하므로 절대로 사용하지 마십시오.
_logger.logp(Level.INFO, CLAZZ_NAME, METHOD, "Messages.PROCESS_RECS");
_logger.logp(Level.SEVERE,CLAZZ_NAME,METHOD,Messages,RCP_XML_PROCESSING_ERROR
throwable);
다음 코드 예제는 추적을 보여줍니다.
if (_logger.isLoggable(Level.FINE))
_logger.logp(CLASS_NAME_METHOD,"Setting activities for page
" + _model.getName() + ":"); }
위의 예제에서는 _model.getName() 호출이 단순히 String을 리턴하는 것보다 복잡한 처리를 수행해야 한다고 가정합니다. String을 리턴하기만 하는 경우 보호가 필요하지 않습니다.
private GUID methodX(URL url, IProgressMonitor pM, boolean overrideCache) {
final String METHOD="methodX";
if (logger.isLoggable(Level.FINER)) {
logger.entering(CLASSNAME, METHOD, url==
null?"null":url.toExternalForm());
}
…
}
logger.exiting(CLASSNAME, METHOD, res);
"exiting" 호출은 이 메소드에서 리턴하는 결과를 로깅하므로 잘못된 사항이 있으면 이를 해결하기 위한 디버깅용으로 매우 유용합니다.
public void showApplication(URL url, String pageId, IProgressMonitor
progressMonitor)
throws IllegalArgumentException, CompositeApplicationException {
final String METHOD="showApplication";
if (logger.isLoggable(Level.FINER)) {
logger.entering(CLASSNAME,
METHOD,
new Object[] {url, pageId, progressMonitor});
}
} catch (RuntimeException e) {
logger.logp(Level.SEVERE,CLASS NAME, METHOD
Messages.PORTAL APP JOB UPDATE ERROR, e);
throw new CompositeApplicationException(e);
}
실행 중 한 번 사용자의 로거 레벨을 확인한 후 사용자 호출을 보호하려고 할 때마다 레벨을 묻는 대신 이 캐시된 레벨을 참조하는 것이 나을 수 있습니다. 그러나 이는 권장사항은 아닙니다. OSGi 명령 프롬프트와 같은 로거 레벨 구성의 동적 업데이트 사항에 코드가 응답하지 않을 수 있기 때문입니다.