Skip to content

Logging and Trace

Andrew Rouse edited this page Dec 5, 2025 · 5 revisions

Logging within Open Liberty uses our own logging framework.

The log levels used by our logging framework are listed in the docs.

Setting up your project for logging

  1. In your bnd.bnd file, add a dependency on the logging project

    -buildpath: \
        com.ibm.ws.logging;version=latest
    
  2. In your bnd.bnd file, declare a trace group for the bundle trace

    WS-TraceGroup: MYFEATURE
    
  3. Either create an nlsprops file, or import a package containing your nlsprops file

Adding logging to your classes

Log messages are those at INFO level or above. They're intended for users to read and they're output to the messages.log file. Messages at AUDIT level and above are additionally output to the console log.

All log messages at INFO level or above must be translated by including the actual message in an nlsprops file and referencing the message key in your code.

  1. Open the package-info.java in the same package as your class (create it if one does not exist) and add the @TraceOptions annotation with the messageBundle attribute set.

    @TraceOptions(messageBundle = "io.openliberty.example.internal.ExampleMessages")
    package io.openliberty.example.internal.something.impl;
    
    import com.ibm.websphere.ras.annotation.TraceOptions;

    The messageBundle parameter should be the fully qualified name of your nlsprops file, without the nlsprops extension.

  2. Declare a TraceComponent at the top of your class.

    import com.ibm.websphere.ras.Tr;
    import com.ibm.websphere.ras.TraceComponent;
    [...]
    private static final TraceComponent tc = Tr.register(MyClass.class);

    You must do this in every class in which you want to log messages. Make sure you're importing these classes from com.ibm.websphere.ras.

  3. Log messages using the methods on Tr

    Tr.error(tc, "MYFEAT0001E.some.error.name", theError);
    Tr.warning(tc, "MYFEAT0002W.missing.property", name, component, defaultValue);

    Remember, all log messages at INFO or above must be translated so you should always be using a message key in your logging statement which corresponds to an actual message in your nlsprops file.

    The message in the nlsprops file can contain placeholders which will be substituted by the additional objects passed to the logging method.

    The nlsprops file for these logging calls may look like this:

    MYFEAT0001E.some.error=MYFEAT0001E: Some error has occurred and the action cannot be completed. The error is {0}
    MYFEAT0001E.some.error.explanation=Some error has occurred. This might occur because ...
    MYFEAT0001E.some.error.useraction=Review the error message and adjust some configuration
    
    MYFEAT0002W.missing.property=MYFEAT0002W: The {0} configuration property in the {1} component is missing. The default value of {2} will be used.
    MYFEAT0002W.missing.property.explanation=The property has not been set, so a default value is being used instead. Processing can continue, but the result may be incorrect if ...
    MYFEAT0002W.missing.property.useraction=Set the property by ... to ...

Adding trace to your classes

Trace messages are messages logged at the EVENT or FINE level and below. These are not intended for end users, are mostly used by support, are only logged if trace is enabled for the relevant component and are only output in the trace.log file.

Entry and exit trace is automatically added to every method in your code, unless suppressed using @Trivial.

You might still want to manually add trace:

  • If you've disabled the automatic trace for a method but still want to trace a subset of the data
  • If you want to describe what the server is doing at a higher level (using EVENT trace)
  • If you need to trace information that is not captured by the arguments or return values of your methods (usually using DEBUG trace)
  1. Open the package-info.java in the same package as your class (create it if one does not exist) and add the @TraceOptions annotation with the traceGroup attribute set.

    @TraceOptions(traceGroup = "MYFEATURE")
    package io.openliberty.example.internal.something.impl;
    
    import com.ibm.websphere.ras.annotation.TraceOptions;

    If there's both logging and trace within the package, then the traceGroup and messageBundle should both be set.

  2. Declare a TraceComponent at the top of your class.

    import com.ibm.websphere.ras.Tr;
    import com.ibm.websphere.ras.TraceComponent;
    [...]
    private static final TraceComponent tc = Tr.register(MyClass.class);

    You must do this in every class in which you want to add trace. Make sure you're importing these classes from com.ibm.websphere.ras.

  3. Log trace information in your code

    if (TraceComponent.isAnyTracingEnabled() && tc.isEventEnabled()) {
        Tr.event(this, tc, "Created the widget for request id " + requestId);
    }
    if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
        Tr.debug(this, tc, "Widget parameters requested", parameters);
    }

Notes:

  • Trace statements are not translated
  • Trace statements cannot have placeholders (use Tr.formatMessage if you really need them)
  • Trace statements must be surrounded by an if statement with both checks to ensure that trace statements have minimal impact on performance.
  • this should be passed as the first parameter when tracing within non-static methods. This populates the id=xxxxxxxx field in the trace.log.
    • static methods should omit this parameter
  • Any additional parameters after the trace message will be printed out on subsequent lines in the trace.log
  • Be extremely careful about doing any work within the if block. If you do anything that has any side-effects, you can end up making your code behave differently when trace is enabled which will make tracking down issues very difficult.

Eclipse templates

You can import Eclipse templates to make it quicker to add trace statements here: Open Liberty Logging templates

Logging in FAT tests

In FAT tests, we can't use the same logging framework and we have to do logging differently depending on whether we're logging in code that runs on the client side or on the server side of the FAT test.

Logging on the client side

Use com.ibm.websphere.simplicity.log.Log to log messages:

Log.info(MyClass.class, "myMethod", "This is the log message");

Log messages logged this way will appear in output.txt.

IMPORTANT: Messages printed to System.out will not appear in output.txt, so be sure to use Log instead.

Logging on the server side

Use java.util.logging to log messages:

private static final Logger LOG = Logger.getLogger(MyClass.class.getName());
...
LOG.info("This is my log message");

Log messages at INFO or above will appear in messages.log.

Anything printed with System.out will also appear in messages.log.

Clone this wiki locally