Express (Distributed operating systems), v8.0 > Troubleshoot and support > Analyzing application server Java system dumps with the IBM Monitoring and Diagnostic Tools for Java - Dump Analyzer > Write Dump Analyzer modules for WAS diagnostics - Tutorial


Tutorial: Writing Dump Analyzer modules for WAS diagnostics


Write and Formatting Reports

In the previous topic, we showed how to print the contents of the WAS thread pool data structures, but with a rather primitive formatting (one line per field, no titles, a simple blank like to separate groups of fields). Let's add some more sophisticated constructs to provide a better format for the output:

public class WASThreadPoolsSample2 extends WASAnalyzerBase implements IReport {

public IAnalysisReport produceReport() { IAnalysisReport out = allocateReport(null); ObjectWrapperCollection pools = ObjectWrapperCollection.getObjectInstances(getContext(), "com/ibm/ws/util/ThreadPool");

/*NEW*/ out.printField("Number of thread pools", pools.size());

for (int index = 0; index < pools.size(); index++) { ObjectWrapper pool = (ObjectWrapper) pools.get(index);

/*NEW*/ out.startSection("Thread Pool", IAnalysisReport.TAG_STANDOUT); {

pool.printValueAtPath(out, "Pool name", "name");

/*NEW*/ out.startFormatSection(IAnalysisReport.FORMAT_COLUMNS, "1 1"); { pool.printValueAtPath(out, "Min size", "minimumPoolSize_"); pool.printValueAtPath(out, "Max size", "maximumPoolSize_"); /*NEW*/ } out.endSection();

pool.printValueAtPath(out, "Current size", "poolSize_"); pool.printValueAtPath(out, "List of Threads", "threads_");

/*NEW*/ } out.endSection();

} return out; } }

Here is a fragment of the output:

Number of thread pools: 14

Thread Pool: Pool name: "ORB.thread.pool" Min size: 10 Max size: 50 Current size: 0 List of Threads: java/util/HashMap@0x00AA7B98

Thread Pool: Pool name: "HAManager.thread.pool" Min size: 2 Max size: 2 Current size: 1 List of Threads: java/util/HashMap@0x0102D520

...

The key aspects are as follows:


Print values not coming directly from a field of an object

The printValueAtPath() method in ObjectWrapper is excellent for printing the value of some field within a particular object instance from the dump. But what if we want to print in the report a value that does not come directly from an object's field, but that is computed during the analysis itself (for example the sum of two fields), or, as in this example, the number of entries in the collection of objects obtained through ObjectWrapperCollection.

The construct to use in this case is:

out.printField("Number of thread pools", pools.size());

The printField() method, implemented by the report object, is similar to printLiteral(), but it takes an arbitrary value (integer, String, etc.) as an argument and prints that value.

One might be tempted, rather than using printField(), to simply dynamically generate a string containing the desired value and pass it to printLiteral(). This should be avoided, and printLiteral() should be used only with constant strings (literals). This is because:


Group related report items into sections

In the previous example, we used a simple blank line generated with printLiteral("") to separate different groups of related items, such as the information relative to each of the thread pool objects. A more flexible way to do this is to use the sections facility of the report object:

out.startSection("Thread Pool"); {
    // ... some contents for the report, as the body of this section
} out.endSection();

Each section has a title, and its body is formatted in the output in a way that makes it clear that it belongs under the title of this particular section, and distinct from other parts of the report that are not within that section. Typically, this is accomplished by indenting the body of the section under its title, but there might be other typesetting tricks used in other output formats.

The TAG_STANDOUT option further refines how the section is presenting, by forcing some white space (blank lines) to separate it from adjacent sections.

Sections may be nested inside other sections to an arbitrary depth to provide a complex structure for a report. In fact, most long reports consist of many sections following each other and/or nested within each other.

Notes:


Special formatting for fields or groups of fields

Beside the ability to group related fields into sections as described above, the report object also provides some mechanisms to control how various fields are presented. The most commonly-used is to put several fields onto a single line, instead of having each field on its own line:

out.startFormatSection(IAnalysisReport.FORMAT_COLUMNS, "1 1"); {
     pool.printValueAtPath(out, "Min size", "minimumPoolSize_");
     pool.printValueAtPath(out, "Max size", "maximumPoolSize_");
} out.endSection();

With this construct, the two fields "Min size" and "Max size", which constitute the body of the startFormatSection() block are shown in two columns on a single line.

Notes:


Next Topic


Print Groups of ObjectWrapper Fields