Access Keys:
Skip to content (Access Key - 0)









Tracing Made Easy in SLEE 1.1

Print this page

Introduction

In the time since SLEE 1.0 was released, the TraceFacility has proved to be quite cumbersome to use in practice, and needed an overhaul to support new features in SLEE 1.1.

Application-level tracing was provided in SLEE 1.0 using the javax.slee.facilities.TraceFacility interface. This allowed SBBs to generate trace messages that could be logged or intercepted by JMX management clients in a standard way. Unfortunately in the time since SLEE 1.0 was released, the TraceFacility has proved to be quite cumbersome to use in practice, and needed an overhaul to support new features in SLEE 1.1. This page describes the legacy TraceFacility interface and its SLEE 1.1 replacement, javax.slee.facilities.Tracer, implemented by Rhino 2.0.

Why does SLEE need its own tracing interface? What about Java Logging/Log4j/Commons Logging?

Developers using SLEE for the first time often ask why they can't just use their favourite logging API instead of SLEE tracing. There is nothing stopping a developer using a different logging API in their SBBs, provided that they deploy the appropriate logging library, or the SLEE implementation provides one. However, using another logging API instead of SLEE tracing is strongly discouraged for two main reasons:

  1. Portability. An SBB that uses a third-party logging API may not be portable to other SLEE platforms. One of the goals of SLEE is to provide a rigourously-defined application environment, so that an application can be deployed on different SLEE implementations without changing source code or recompilation. Using a third-party logging API will make this more difficult.
  2. Integration with management clients. SLEE trace messages (in SLEE 1.0 and 1.1) are defined to be JMX notifications. This means that JMX management clients can use the standard JMX NotificationListener interface to receive trace messages. This gives SLEE vendors and system integrators maximum flexibility when designing management interfaces. Trace messages can be simply logged to a file, or transmitted to a remote management console. Some logging APIs can provide similar functionality, but with SLEE tracing this is standard and automatically available to all SLEE developers.

So in summary, using SLEE tracing allows developers to automatically gain these benefits of using the SLEE platform. Some developers might not have liked the old SLEE 1.0 TraceFacility API, and so used another logging API anyway, but the improvements in SLEE 1.1 make tracing as easy to use as other popular logging APIs.

Tracing in SLEE 1.0

In SLEE 1.0, tracing was provided by the TraceFacility interface. This interface was only available to SBBs, and was obtained using JNDI lookup. Typically this would be done in an SBB's setSbbContext() lifecycle method, to set an instance variable that could be used later. For example:

import javax.slee.Sbb;
import javax.slee.SbbContext;
import javax.slee.facilities.TraceFacility;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public abstract class MySbb implements Sbb {

    private TraceFacility traceFacility;
    private SbbContext context;

    public void setSbbContext(SbbContext context) {
        this.context = context;
        try {
            this.traceFacility = (TraceFacility) new InitialContext().lookup("java:comp/env/slee/facilities/trace");
        } catch (NamingException e) { ... }
    }

Later, when the SBB wanted to generate a trace message, it would call TraceFacility.createTrace(), passing a ComponentID (such as the SBB's SbbID or ServiceID), a trace level, a message type string, the message string, and a timestamp:

// Generate an INFO trace using the SBB's SbbID as the component ID
traceFacility.createTrace(context.getSbb(), Level.INFO, "MySbb", "An event has occurred", System.currentTimeMillis());

Compared to other logging APIs, this is not the simplest way of generating a log message. This is complicated further by the fact that createTrace() may throw a checked exception, UnrecognizedComponentException, if the ComponentID argument is invalid. Applications can of course wrap createTrace() with other methods to simplify generating traces, but this is more work for the application developer.

Another problem is that it is not clear who is the source of a trace message. The createTrace() method requires a ComponentID parameter to identify the source. In principle the SBB could use a ServiceID, SbbID or any other valid SLEE component ID when generating a trace. This is a problem because the same SBB can potentially be deployed in several services, so if an SBB generates traces using its SbbID, a management client cannot tell which service the SBB is being used in. Applications could encode additional contextual information about the source, but this is more work and should be automatic.

The SLEE 1.1 tracing APIs remove these problems while still providing the benefits of a standardised SLEE trace facility.

Tracing in SLEE 1.1

Tracer Interface

In SLEE 1.1, there are more components that may need tracing support. In addition to SBBs, trace messages may also be generated by profile abstract classes and resource adaptors, and potentially any other SLEE subsystem.

All of these components may use the SLEE 1.1 javax.slee.facilities.Tracer interface. The Tracer interface will be familiar to users of other logging APIs. It provides methods for generating traces at different trace levels, and these methods take a string and an optional Throwable parameter. The main tracing methods are shown below (other methods not shown for brevity):

package javax.slee.facilities;
...
public interface Tracer {
    ...
    public void severe(String message);
    public void severe(String message, Throwable cause);
    public void warning(String message);
    public void warning(String message, Throwable cause);
    public void info(String message);
    public void info(String message, Throwable cause);
    public void config(String message);
    public void config(String message, Throwable cause);
    public void fine(String message);
    public void fine(String message, Throwable cause);
    public void finer(String message);
    public void finer(String message, Throwable cause);
    public void finest(String message);
    public void finest(String message, Throwable cause);
    ...
}

Obtaining a Tracer

Components obtain Tracers by calling the getTracer() method on the particular component's context object, for example:

  • SBBs call SbbContext.getTracer(String).
  • Profiles call ProfileContext.getTracer(String).
  • Resource Adaptors call ResourceAdaptorContext.getTracer(String).

The string parameter in the above methods is the tracer name. This is a hierarchical name, following Java naming conventions, where the different levels in the hierarchy are delimited by a dot. For example, a tracer named "com.foo" is the parent of "com.foo.bar". Components may create any number of tracers, with different names, for different purposes. Tracers inherit the trace level of their parent in the hierarchy. The tracer named "" (empty string) is the top-level or root tracer. The hierarchical naming is a convention used in most logging APIs, and allows an administrator to easily enable or disable tracing for an entire hierarchy of tracers.

Example

The example SLEE 1.0 SBB shown above would look like this if using SLEE 1.1 tracing:

import javax.slee.Sbb;
import javax.slee.SbbContext;
import javax.slee.facilities.Tracer;

public abstract class MySbb implements Sbb {

    private Tracer tracer;
    private SbbContext context;

    public void setSbbContext(SbbContext context) {
        this.context = context;
        this.tracer = context.getTracer("MySbb");
    }

    ...

    // Generate an INFO trace
    tracer.info("An event has occurred");
    ...

This is clearly much more convenient, and will be familiar to users of other logging APIs.

Notification Sources

In the code example above, nowhere did the SBB have to specify its SbbID or ServiceID as the source of the trace message. In SLEE 1.1 this is automatic. SLEE 1.1 introduces the NotificationSource interface, which the SLEE automatically adds to JMX notifications generated by SLEE tracers, so that JMX clients can easily identify the source. The NotificationSource explicity identifies the component that generated the trace, so a management client can easily see which service and SBB the trace came from, allowing filtering by service or SBB. This solves the problem of identifying which SBB in which service generated a trace message.

Management Interface

The TraceMBean management interface has been extended in SLEE 1.1 so that management clients can easily enable tracing for a particular NotificationSource and tracer name:

package javax.slee.management;
...
public interface TraceMBean {
    ...
    public void setTraceLevel(NotificationSource notificationSource, String tracerName, TraceLevel level)
        throws NullPointerException, UnrecognizedNotificationSourceException,
               InvalidArgumentException, ManagementException;
    ...
}

Rhino 2.0's command-line console (rhino-console) and web console interfaces have been updated to support SLEE 1.1. The example below shows an administrator using rhino-console to enable Finest-level tracing for the root tracer, for the Proxy SBB in the SIP Proxy service:

[Rhino@localhost (#0)] settracerlevel sbb 
    "service=ServiceID[name=SIP Proxy Service,vendor=OpenCloud,version=1.8],  
     sbb=SbbID[name=ProxySbb,vendor=OpenCloud,version=1.8]" "" Finest
Set trace level of 
    SbbNotification[service=ServiceID[name=SIP Proxy Service,vendor=OpenCloud,version=1.8],
                    sbb=SbbID[name=ProxySbb,vendor=OpenCloud,version=1.8]] root tracer to Finest

The second parameter to the "settracerlevel" command is the string representation of an SBB NotificationSource, specifying the service and SBB. Tab-completion in rhino-console means this does not need to be typed in full. The third parameter ("") represents the root tracer, but the string "root" may also be used.

Backward compatibility

SLEE 1.1 still supports the TraceFacility interface for backward compatibility, but it has been deprecated and may be removed in a later version of the specification.

Conclusion

Tracing in SLEE 1.1 has been greatly improved from SLEE 1.0. It will be familiar to users of most other logging APIs, and provides the benefits of application portability and the use of JMX notifications for integration with management clients. It is strongly recommended that SLEE component developers migrate to the SLEE 1.1 tracing API.

Adaptavist Theme Builder Powered by Atlassian Confluence