private static final String CLAZZ_NAME = MyClass.class.getName(); private static final String PKG = MyClass.class.getPackage().getName(); private static final String LOG_RB = PKG + "." + “Messages.properties); private static Logger _logger = Logger.getLogger(PKG,LOG_RB);
Substitute your class name for MyClass and ensure you have a properties file with the same name as the leaf node of the package.
java.util.logging.LogManager.getLogger(String name) returns the logger with a matching name if it already exists. Otherwise it returns null. There is no guarantee that a given logger will exist when your class gets instantiated since the order of class instantiation is not determinate. Even if it were currently, the order could change later. Therefore, it is necessary to use the get methods from the Logger class to ensure that a Logger is returned. Whether you use LogManager or Logger to get a logger, no more than one instance of a named logger is ever in existence within a VM at any given time.
Additionally, since it is possible to instantiate a logger at first with no resource bundle and then later use it with a resource bundle, consistently requesting it by means of the Logger class ensures that the expected resource bundle will be available. If you use LogManager you will get the logger (if it exists). However, it must already have an associated resource bundle. There are alternatives, such as testing to see if the logger has a ResourceBundle already, and if not, using Logger,getLogger(String name, String resourceBundleName) to fix the situations. Alternatively, you could adopt the convention of only using the logbr methods of Logger instead.
com.ibm.rcp.mypackage.level=FINEST
If you want to hear less from other JSR47 loggers, simply change the default values in the rcpinstall.properties to SEVERE.
The system log can be found in <workspace>\logs\error-log-0.xml where n is a number 0 (current log) or 1 log from the last time it was run.
The system trace file can be found in <workspace>\logs\trace-log-0.xml where n is a number 0 (current log) or 1 log from the last time it was run.
if(_logger.isLoggable(WARNING)){ _logger.logp(WARNING,CLAZZ_NAME,method, "warn.unable.to.get.preference", new Object[]{pid,key}); }
INFO
Done with install operations
Don't: Use INFO for debug information, for tracing program execution, in potentially frequently repeating events, or to simply confirm an event unless it will be useful in determining the cause of a problem with a related event.
WARNING
Failed to retrieve page file for URL EXPEDITOR.png.
Don't: Use WARNING if the problem completely or severely eliminates the use of a function, or for information messages that do not indicate impaired function.
SEVERE
Error loading plugin customization file
Don't: Use SEVERE if all or most functionality will continue to be available or if the problem is transient.
Tracing is off by default. Trace is intended for use by developers, Quality Engineers and Support.
There are three trace levels: FINE, FINER and FINEST.
FINE: Use this level for significant events that explain the flow or state of the system when trying to understand or debug a problem. These are usually at the level of object creation, catch clauses for exceptions that do not constitute errors, and so on.
FINEST: Finest is usually thought of as developer or debug tracing. This is used during development, when attempting to learn the behavior of a system at a fine level of detail and when trying to diagnose difficult problems once the code is released.
Tracing is a valuable tool, both during and after development. There is a common misunderstanding that there is "Developer Only" tracing. Tracing that developers want to be able to turn on and off should be done using the java.util.logging.Logger API. The level should be FINEST. Such tracing can be valuable to support when diagnosing a difficult customer problem. Having it available will be one factor in reducing the support team’s dependence on development. The rule of thumb should be: If it is valuable now, it may be valuable later. Use Java™ logging at the FINEST level and you will have virtually no impact on performance (with proper guarding), and you will create a valuable tool for someone else. If you use println or printStackTrace you are not tying into the manageable Java logging framework, and are likely going to create a distraction for someone else.
if (_logger.isLoggable(Level.INFO)) { _logger.logp(Level.INFO, CLAZZ_NAME, "execute", "info.process.reqs"); }
_logger.logp(Level.SEVERE,CLAZZ_NAME,"run","err.rcpapplication.error", throwable);
The following code examples illustrate tracing.
if (_logger.isLoggable(Level.FINE)) _logger.fine("Setting activities for page " + _model.getName() + ":");
private static final String CLASSNAME = CompositeApplicationAdapterServiceImpl.CLASSNAME; // If you refactor the class name changes private GUID methodX(URL url, IProgressMonitor pM, boolean overrideCache) { if (logger.isLoggable(Level.FINER)) { logger.entering(CLASSNAME, "methodX", url== null?"null":url.toExternalForm()); } GUID res = null; … }
} finally { if (logger.isLoggable(Level.FINER)) { logger.exiting(CLASSNAME, "methodX", res); } }
The "exiting" call is in a finally clause so that it logs the exit even if the method throws an exception. It also logs the result being return from this method, which is, again, very useful for debugging purposes to figure out what, if anything, went wrong.
public void showApplication(URL url, String pageId, IProgressMonitor progressMonitor) throws IllegalArgumentException, CompositeApplicationException { if (logger.isLoggable(Level.FINER)) { logger.entering(CLASSNAME, "showApplication(URL,String,IProgressMonitor)", new Object[] {url, pageId, progressMonitor}); } } catch (RuntimeException e) { logger.log(Level.SEVERE, PortalCaiUIPlugin.getString( "str.caiuiplugin.calling.applications.update.job.error"), e); throw new CompositeApplicationException(e); }
It may seem tempting to check the level of your logger once during your execution, and then simply refer to that cached level instead of asking for the level each time you want to guard your calls. This is not recommended, however, since it can cause your code to not respond to dynamic updates to logger level configuration such as via the OSGi command prompt.