Package com.ibm.ras

The Java RAS Toolkit provides features to enhance the Reliability, Availability and Serviceability (RAS) of your Java applet or application.  Currently, the RAS Toolkit includes message logging and tracing functions and a RAS Manager, which configures the various RAS objects.  This overview provides guidance and instruction to help you get the most out of the RAS Toolkit.  Please take a few minutes to read through this material.  It will put you on the fast track to production quality code.

See:
          Description

Interface Summary
RASIEvent RASIEvent defines the methods that must be implemented to contain RAS message or trace data.
RASIFormatter RASIFormatter defines the methods that must be implemented to format RAS events.
RASIHandler RASIHandler defines the methods that must be implemented to process RASEvents generated by a RASLogger.
RASILogger RASILogger/code> defines the methods which are common to objects that wish to create RAS message and trace data.
RASIMaskChangeListener RASIMaskChangeListener defines the methods that must be implemented to process changes that occur in the RASHandler message and trace masks.
RASIMessageEvent RASIMessageEvent defines a set of constants related to RASMessageEvents.
RASIMessageLogger RASIMessageLogger defines a set of methods that must be implemented to create RAS messages.
RASIObject RASIObject/code> defines the methods which are common to the RASILogger, RASIHandler and RASIFormatter interfaces.
RASITraceEvent RASITraceEvent defines a set of constants related to RASTraceEvents.
RASITraceLogger RASITraceLogger defines a set of methods that must be implemented to create RAS trace data.
 

Class Summary
RASConsoleHandler RASConsoleHandler implements a RASHandler that writes to the console (System.out).
RASCopyright This class contains copyright statements which are included in each class file of this package.
RASEvent RASEvent is the parent of all RASMessageEvent and RASTraceEvent objects.
RASFileHandler RASFileHandler implements a RASHandler that writes to a file.
RASFormatter RASFormatter is the parent of all classes which format RAS events for display.
RASHandler RASHandler implements the RASIHandler interface and is the parent of all classes which process the output of the RASLogger classes.
RASLogger RASLogger implements the RASILogger interface and is the parent of all classes which create message and trace data.
RASMessageCatalog The RASMessageCatalog class is used within the RAS system to format messages according to the current locale (that is, in the desired language).
RASMessageEvent A RASMessageEvent encapsulates all of the information generated by a RASMessageLogger.
RASMessageFormatter A RASMessageFormatter formats a RASMessageEvent for display.
RASMessageLogger The RASMessageLogger is one of two RASLogger sub-classes provided in this package.
RASObject RASObject defines the methods which are common to the RASLogger, RASHandler and RASFormatter classes.
RASSocketHandler RASSocketHandler implements a RASHandler that writes to a TCP socket.
RASTraceEvent A RASTraceEvent encapsulates all of the information generated by a RASTraceLogger.
RASTraceFormatter A RASTraceFormatter formats a RASTraceEvent for display.
RASTraceLogger The RASTraceLogger is one of two RASLogger sub-classes provided in this package.
RASUtil This class contains constants and utility methods used by this package.
 

Package com.ibm.ras Description

The Java RAS Toolkit provides features to enhance the Reliability, Availability and Serviceability (RAS) of your Java applet or application.  Currently, the RAS Toolkit includes message logging and tracing functions and a RAS Manager, which configures the various RAS objects.  This overview provides guidance and instruction to help you get the most out of the RAS Toolkit.  Please take a few minutes to read through this material.  It will put you on the fast track to production quality code.


Class Structure

The RAS Toolkit is contained in the package com.ibm.ras.  In support of message logging and tracing, the RAS Toolkit contains two major classes: The RASLogger ("logger") classes provide the methods to create a message or trace log entry.  The RASHandler ("handler") classes direct these log entries to a destination, such as the console, a file, or a TCP socket.

The RASLogger class is the parent of all classes which create message or trace data.  When constructing a RASLogger, a name by which this RASLogger is known should be specified.  We recommend that a description also be provided.  In simple environments, say, in which a Java application is being developed for personal use, a RASLogger description may not be necessary.  But, in more complex environments, such as a business in which many applets are served, a "RAS manager" may be included to provide graphical tools which control message and  trace logging.  Here, the name is required and a description of each RASLogger is very useful.

Before you can use a RASLogger, you must associate with it at least one RASHandler. Use the RASLogger.addHandler method to accomplish this.  It is possible to associate more than one RASHandler with a RASLogger to send the log entries to multiple destinations, possibly formatted differently for each. RASLogger is an abstract class because it lacks methods to send data to its RASHandlers.  Extensions to RASLogger, RASMessageLogger and RASTraceLogger provide these functions for message logging and tracing, respectively.

RASHandler is the parent of all classes which process the output of the RASLogger classes. A RASHandler may be configured directly, but the convenience classes RASConsoleHandler, RASFileHandler and RASSocketHandler are provided to direct log entries to the console, a file or a TCP socket, respectively.

Since it is possible to direct both message and trace data to the same destination (the console or a socket, for example), the RASHandler has methods to support the logging of message and trace data. However, if the message and trace data are bound for different destinations (two separate files, for example), two RASHandlers can be configured. Naturally, only the methods appropriate to the type of logged data will be used in each RASHandler.

For those applications which would rather be, rather than use, loggers or handlers, interfaces are provided to allow such implementations:


Message Logging

The purpose of a message log is to provide information to the users of an application (as distinct from trace, which is intended for developers or a service team).  As a general guideline, you should only log a message if the information it contains is of value to the user.

The logging service provides for three different types of log messages:  informational, warning and error. For warning and error messages, you would normally provide details telling the customer how to rectify the situation.

The RASMessageLogger class extends RASLogger to provide message-specific function.  By default, message logging is enabled when a RASMessageLogger is created.

Since message logging is intended to provide information to the end-user of an application, message texts must be translated into different national languages and displayed according to a selected locale.  Normally, the text for a set of messages is stored in one or more message files.  Text strings are accessed by a "key," which is a name for the message text.  This mechanism allows the message text to be separated from the program that uses it, making translation into different national languages easier.

A message logger, therefore, must be told which message file to search.  Two mechanisms are available to accomplish this:

If more than one message file is used, it may be desirable to register one (the most frequently used) with setMessageFile and only use the msg methods when an alternate message file is needed.

Message files are implemented in the RAS Toolkit through ResourceBundles.  Typically, applications will use either a ListResourceBundle or a PropertyResourceBundle to contains its messages.  The choice is arbitrary, though some believe that there is less chance of translation problems with the PropertyResourceBundle, which just contains a set of "key=value" pairs and no Java code.

The message and msg methods each include in their parameters the name of the class and method which generated the message.  In all cases, one can use the methods which take String className as the second parameter.  When tracing in non-static methods, one can use the message and msg methods that take "this" (the object being traced) as the second parameter. This is a convenience to the programmer, as the class name can be derived from any Object.  (In static methods, an object does not exist, so these methods cannot be used.)   The price for convenience, however, is performance.  It takes more effort to derive the class name from "this" than to use the hard-coded string.

The format method in the RASMessageEvent class makes use of the java.text.MessageFormat class to substitute into the message text information known only at run-time.  Consider the following.  In a message file, a key/message pair might be:

HOT_DAY=On {0}, it is {1} degrees.
Your message method call might be:
String day = "Monday";
Integer temp = new Integer(75);
logger.message(RASMessageEvent.INFO, this, "methodName", "HOT_DAY", day, temp);
The logged message text is:  "On Monday, it is 75 degrees."

To support this variable substitution, an overloaded set of message and msg methods is provided by RASMessageLogger that take zero to two individual objects.  One method (of each type) takes an array of inserts, to handle any cases in which a message requires more than two inserts.

Message Types

Messages are each assigned a type.  Message types are defined by the RASIMessageEvent.TYPE_XXXX constants.  See the discussion on controlling logging for more information on this point.  Message types can be the logical OR of any of the defined types.  However, the types defined by RASMessageEvent are designed to be independent:  a message can't be informational and a warning as well.  Extensions to the RASMessageEvent class might make this possible.  For example, "internal" and "external" might be added to the type set to identify whether the message pertains to something detected within or outside an application.  In this case, a message could be of TYPE_ERROR | TYPE_EXTERNAL.

Message Output Format

A RAS message has several fields which are typically constant for a given RASMessageLogger.  These are: These fields are optional in a RAS message and default to an empty string if not specified.  Because they tend to be constant for a given RASMessageLogger, they are not part of the message method.  Instead, the RASMessageLogger has the following methods to set these values (with corresponding get methods, as well): The following is an extract from a log file produced by the message service, showing a typical message entry:

1999.01.05 11:11:03.612 com.ibm.ras.samples.RASSample messageSample IBM Cool Java Stuff Communications orion.raleigh.ibm.com JohnDoe Starting the RAS Log Server.

The components of the message are:

The message format illustrated above is the default format produced by the message service. You can control the format of the message by associating a RASFormatter with a RAS event class using the RASHandler.addFormatter method.

Tracing

The purpose of tracing is to provide sufficient information to a developer or service team to diagnose a problem remotely (for example, when the application is in production on a customer site). Normally an application will run with tracing turned off. When a problem occurs, it can be turned on to gather the data needed to understand the problem.

It is tempting to leave the addition of trace to your code until the very end of your development cycle. Experience shows this to be a mistake. If done correctly, a trace facility can be a great aid in tracking down and solving bugs during development. If you find that your trace files are not helping you in problem diagnosis, then they most likely do not contain sufficient information. If you can't find a problem in your code using a trace file, what chance will a service team have? Bite the bullet, improve your tracing!

The RASTraceLogger class extends RASLogger to provide trace-specific function.  By default, tracing is disabled when a RASTraceLogger is created.  Four groups of methods are available to trace program flow and key checkpoints:

Each of these methods includes in its parameters the name of the class and method which generated the trace.  In all cases, one can use the methods which take String className as the second parameter.  When tracing in non-static methods, one can use the entry,exit, exception  and trace methods that take "this" (the object being traced) as the second parameter. This is a convenience to the programmer, as the class name can be derived from any Object.  (In static methods, an object does not exist, so these methods cannot be used.)   The price for convenience, however, is performance.  It takes more effort to derive the class name from "this" than to use the hard-coded string.

Because tracing is intended for developers and service teams, no provision for the translation of trace data to different national languages is provided.

Trace Types

Trace types are defined by the RASITraceEvent.TYPE_XXXX constants.  See the discussion on controlling logging for more information on this point.

As a convenience, the entry and exit methods will automatically add TYPE_ENTRY_EXIT to the type specified on the method call.  The set of trace types can be altered, if necessary, by extending the RASTraceEvent class.

Trace Output Format

The following is an extract from a log produced by the tracing service, showing a typical trace entry:

06:56:34:965 Thread-1 TLogger RASTest run Test trace logging
11:11:02.921 com.ibm.ras.samples.RASSample traceSample Thread-1 TrcLogger Trace is valuable when Bad Things happen to Gooodd Code.
The components of the trace entry are:

The trace format illustrated above is the default format produced by the tracing service. You can control the format of the traced data by attaching a different RASFormatter to the RASHandler.

A Note on Trace Performance

For maximum performance when tracing is off, wrap your trace calls in a test of the RASTraceLogger.isLogging variable.  This boolean is set true when the RASLogger is "on" (logging data) and false when it is "off."  For example:
if (traceLogger.isLogging)
  traceLogger.trace(...);
For additional control, the RASTraceLogger.isLoggable method will compare the type associated with trace point with the mask of the RASTraceLogger and each configured RASHandler.  It will return true if the logger and at least one of the handlers will process the trace point.  Thus, the overhead of building the trace entry is avoided if no object is configured to process it.  An example:
if (traceLogger.isLoggable(RASTraceEvent.TYPE_PUBLIC)
  traceLogger.trace(RASTraceEvent.TYPE_PUBLIC,...);

Controlling Message and Trace Logging

Several mechanisms are available to control the logging of message and trace data.  At the highest level, each logger has a public boolean variable, isLogging, which is set true when the logger is "on" and false when it is "off."  By default, RASMessageLoggers are "on" when they are created and RASTraceLoggers are "off."

For finer control, every log point (a place in an application where a call is made to the RAS Toolkit to log message or trace data) is associated with a "type."  For example, a message type might be "warning," or "error."  The set of possible message types is different than the set of trace types and are defined in the RASMessageEvent and RASTraceEvent classes, respectively.

In general, the type of a log point can be the logical OR of any of the types defined by the RASIMessageEvent or RASITraceEvent TYPE_XXXX constants.  Be careful in assigning types, as certain combinations do not make sense.  For example, TYPE_ENTRY_EXIT | TYPE_PUBLIC makes sense and defines the point as an entry to or exit from a public method.  However, TYPE_PUBLIC | TYPE_PRIVATE doesn't make much sense.  A method can't be public and private at the same time.

Loggers and handlers make use of a "mask," which determines the set of types that it will process.  Message and trace data are handled separately, so each type of data has its own mask, which can be changed by the setMessageMask and setTraceMask methods, respectively.  When a log entry is processed, its type is compared to the mask.  If the type is contained in the mask, the log entry is processed; otherwise, it is not.  For example, an informational message will not be processed if the logger's mask only includes warning messages.  It will be processed if the logger's mask is set for informational and warning messages.

Although nothing prohibits this, in general, one would not manipulate the masks of both the loggers and the handlers.  It can be very confusing!  But, different effects can be achieved by controlling the masks in the loggers or the handlers.  A few examples:


Release Notes

Version 1.0


Suggestions/Problem Reports

Please send any suggestions or problem reports to:
Chris Barlock
barlock@us.ibm.com
(919) 254-9964
IBM Tie-line 444-9964