24 How to Create a Custom Report

The Coherence reporting feature provides a capable query definition that allows for any information residing in the Coherence JMX data source to be logged to a text file. After a custom report has been created, it can be included in a report batch and executed on a specified time interval by the ReportControl MBean. For a complete description of the report configuration XML file see the report-config.dtd which is packaged in the coherence.jar file.

24.1 Configuring a Report File

To correctly generate the report file, several elements must be configured. These elements are described in Table 24-1.

Table 24-1 Elements to Configure an Output File

Element Optional/Requited Description

<file-name>

Required

The file name to create or update when the report is executed. For more information, see "file-name Element".

<delim>

Optional

The column delimiter for the report. Valid values are {tab}, {space} or a printable character. The default value is {tab}. If a string longer than one character is entered, the first character in the string is used.

<hide-headers>

Optional

A boolean element to determine if the headers are to be included in the report. If true, the column headers and the report description are not included in the file. The default value is false.


24.1.1 file-name Element

The value of this element will have the output path from the <report-path> element pre-pended to it and the report will be generated in this location. If the Coherence node cannot access this path, then the file will not be created.

24.1.1.1 file-name Macros

There are pre-defined macros that you can use with the file-name element. These macros can add a node name, a batch number, or a date to the generated file name.

Table 24-2 Macros that can be Used with the file-name Element

Macro Description

batch

Will include a batch Identifier into the filename of the report. If the information is kept for a short amount of time or is frequently uploaded into and RDBMS.

date

Will include the date (with the format YYYYMMDD), into the file name of the report. This is used mostly when the data will only be kept for a certain period and then will be discarded.

node

Will include the node ID into the file name string. This configuration setting is helpful when many nodes are executing the same report and the output files will be integrated for the analysis.


24.1.1.2 file-name Macro Examples

The following example will create a file 20090101_network_status.txt on January 1, 2009. The filename will change with the system time on the node executing the report.

<file-name>{{date}}_network_status.txt</file-name>

The following example will create a file 00012_network_status.txt when the report is executed on node 12. Note that due to the volatile nature of the Node Id, long term storage in this manner is not recommended.

<file-name>{node}_network_status.txt</file-name>

The following example will create a file 0000000021_network_status.txt on the 21st execution of the report. Note that due to the volatile nature of the batch, long term storage in this manner is not recommended.

<file-name>{batch}_network_status.txt</file-name>

24.2 Specifying Data Columns

Data columns can be sourced from JMX Attributes, ObjectName key part, JMX composite attributes, JMX joined attributes, Report macros, and Report Constants.

24.2.1 How to Include an Attribute

To include data from MBeans returned from the query-pattern, the report must have a column with an attribute source. This is the most common item that will be included in the report.

Example 24-1 illustrates how to include the RoleName attribute from the query pattern Coherence:type=Node,*.

Example 24-1 Including an Attribute Obtained from a Query Pattern

<column id = "RoleName">
  <type>attribute</type>
  <name>RoleName</name>
  <header>Role Name</header>
</column>

24.2.2 How to Include Part of the Key

A value that is present in an ObjectName key can be obtained from the ObjectNames returned from the query-pattern. This value can subsequently be included in the report.

Example 24-2 illustrates how to include the nodeId key part from the query pattern Coherence:type=Node,*.

Example 24-2 Including Part of an ObjectName Key in a Report

<column id ="NodeId">
  <type>key</type>
  <name>nodeId</name>
  <header>Node Id</header>
</column>

24.2.3 How to Include Information from Composite Attributes

JMX composite values can be used to include part of a composite data attribute in a report.

Example 24-9 illustrates how to include the startTime of the LastGCInfo attribute from the query pattern java.lang:type=GarbageCollector,*.

Example 24-3 Including Information from a Composite Attribute in a Report

<column id="LastGCStart">
   <type>attribute</type>
   <name>LastGcInfo/startTime</name>
   <header>Last GC Start Time</header>
</column>

24.2.4 How to Include Information from Multiple MBeans

A JMX join attribute is required when a report requires information from multiple MBeans. The major considerations when creating a join is to determine both the primary query, the join query and the foreign key. The primary query should be the query that returns the appropriate number of rows for the report. The join query pattern must reference a single MBean and can not contain a wild card (*). The foreign key is determined by what attributes from the primary query that are required to complete the join query string.

The reporter feature that enables joins between MBeans is a column substitution macro. The column substitution allows for the resulting value from a column to be included as part of a string. A column substitution macro is a column ID attribute surrounded by curly braces "{}". The reporter does not check for cyclical references and will fail during execution if a cycle is configured.

24.2.5 Including Multiple MBean Information Example

You can draw information from more than one MBean and include it in a report. This requires a join between the MBeans.

Note:

The major limitation of join attributes is that the result of the join must have only one value.

For example, if a report requires the TotalGets from the Cache MBean (Coherence:type=cache,*) and RoleName from the Node MBean (Coherence:type=Node,*), then a join attribute must be used.

Since a greater number of MBeans will come from the Cache MBean, Coherence:type=Cache,* would be the primary query and the RoleName would be the join attribute. The foreign key for this join is the nodeId key part from the Cache MBean and it must be included in the report. The configuration for this scenario is illustrated in Example 24-4.

Example 24-4 Including Information from Multiple MBeans in a Report

<column id="RoleName">
   <type>attribute</type>
   <name>RoleName</name>
   <header>Role Name</header>
    <query>
       <pattern>Coherence:type=Node,nodeId={NodeFK}</pattern>
    </query>
</column>

<column id ="NodeFK">
  <type>key</type>
  <name>nodeId</name>
  <header>Node Id</header>
</column>

24.2.6 How to Use Report Macros

There are three report macros that can be included in a report:

  • Report Time (report-time)—is the time and date that the report was executed. This information is useful for time series analysis.

  • Report Batch/Count (report-count)—is a long identifier that can be used to correlate information from different reports executed at the same time.

  • Reporting Node (report-node)—is used when integrating information from the same report executed on different nodes or excluding the executing node information from the report.

To include the execution time into the report:

Example 24-5 Including Execution Time in a Report

<column id ="ReportTime">
   <type>global</type>
   <name>{report-time}</name>
   <header>Report Time</header>
</column>

To include the Report Batch/Count:

Example 24-6 Including the Report Batch/Count in a Report

<column id="ReportBatch">
  <type>global</type>
  <name>{report-count}</name>
  <header>batch</header>
</column>

To include the execution node:

Example 24-7 Including the Execution Node

<column id="ReportNode">
  <type>global</type>
  <name>{report-node}</name>
  <header>ExecNode</header>
  <hidden>true</hidden>
</column>

24.2.7 How to Include Constant Values

Report constants can be used to either static values or report parameters. These constants can be either double or string values. Often, these are used in filters to limit the results to a particular data set or in calculations.

Example 24-8 illustrates how to include a constant double of 1.0 in a report:

Example 24-8 Including a Constant Numeric Value in a Report

<column id ="One">
  <type>constant</type>
  <header>Constant1</header>
  <data-type>double</data-type>
  <value>1.0</value>
  <hidden>true</hidden>
</column>

Example 24-9 illustrates how to include the constant string dist-Employee in a report:

Example 24-9 Including a Constant String in a Report

<column id ="EmployeeCacheName">
  <type>constant</type>
  <header>Employee Cache Name</header>
  <data-type>string</data-type>
  <value>dist-Employee</value>
  <hidden>true</hidden>
</column>

24.3 Including Queries in a Report

The query is the foundation of the information included in a report. Each query includes a query pattern, column references, and an optional filter reference. The query pattern is a string that is a JMX ObjectName query string. This string can return one or more MBeans. The column references must be defined in the <columns> section of the report definition file. The filter reference must be defined in the <filters> section of the report section.

Example 24-10 illustrates how to include the list all the Node IDs and RoleNames in the cluster where the RoleName equals CoherenceServer.

Example 24-10 Including a List of the Cluster's NodeIDs and RoleNames in a Report

<filters>
   <filter id="equalsRef">
     <type>equals</type>
     <params>
        <column-ref>RoleRef</column-ref>
        <column-ref>StringRef</column-ref>
     </params>
   </filter>
</filters> 

<query>
   <pattern>Coherence:type=Node,*</pattern>
   <filter-ref>equalsRef</filter-ref>
</query>

<row>
  <column id ="NodeRef">
    <type>key</type>
    <name>nodeId</name>
    <header>Node Id</header>
  </column>

  <column id ="RoleRef">
    <name>RoleName</name>
    <header>Role</header>
  </column>

  <column id = "StringRef">
    <type>constant</type>
    <name>ConstString</name>
    <data-type>string</data-type>
    <value>CoherenceServer</value>
    <hidden>true</hidden>
  </column>
  
</row>

24.4 Using Filters to Construct Reports

Filters limit the data returned in the Report. Filters are either comparison filters or composite filters. Comparison Filters evaluate the results of two columns while composite filters evaluate the boolean results from one or two filters. Comparison filters are equals, greater, and less.

Composite Filter types are and, or, and not. Each composite filter evaluates the filter parameters first to last and apply standard boolean logic. Composite filter evaluation uses standard short circuit logic. Cyclic references checks are not performed during execution. If a cyclic reference occurs, it will create a runtime error.

Example 24-11 illustrates how to define an equals filter where RoleRef and StringRef are defined columns.

Example 24-11 Using an Equals Filter for a Report

<filters>
   <filter id="equals">
     <type>equals</type>
     <params>
        <column-ref>RoleRef</column-ref>
        <column-ref>StringRef</column-ref>
     </params>
   </filter>
</filters>

Example 24-12 illustrates how to define a filter where the number of PacketsResent are greater than PacketsSent (assuming PacketsResent and PacketsSent are valid column references).

Example 24-12 Defining a "Greater Than" Filter for a Report

<filters>
   <filter id="greaterRef">
     <type>greater</type>
     <params>
        <column-ref>PacketsResent</column-ref>
        <column-ref>PacketsSent</column-ref>
     </params>
   </filter>
</filters>

Example 24-13 illustrates how to define an filter where the number of PacketsResent are less than PacketsSent (assuming PacketsResent and PacketsSent are valid column references).

Example 24-13 Defining a "Less Than" Filter for a Report

<filters>
   <filter id="greaterRef">
     <type>less</type>
     <params>
        <column-ref>PacketsResent</column-ref>
        <column-ref>PacketsSent</column-ref>
     </params>
   </filter>
</filters>

Example 24-14 illustrates how to define an and filter (assuming all column-ref values are valid).

Example 24-14 Defining an "And" Filter for a Report

<filters>
   <filter id="equalsRef">
     <type>equals</type>
     <params>
        <column-ref>RoleRef</column-ref>
        <column-ref>StringRef</column-ref>
     </params>
   </filter>

   <filter id="greaterRef">
     <type>greater</type>
     <params>
        <column-ref>PacketsResent</column-ref>
        <column-ref>PacketsSent</column-ref>
     </params>
   </filter>

   <filter>
     <type>and</type>
     <params>
        <filter-ref>greaterRef</filter-ref>
        <filter-ref>equalsRef</filter-ref>
     <params>
   </filter>
</filters>

Example 24-15 illustrates how to define an or filter (assuming all column-ref values are valid).

Example 24-15 Defining an "Or" Filter for a Report

<filters>
   <filter id="equalsRef">
     <type>equals</type>
     <params>
        <column-ref>RoleRef</column-ref>
        <column-ref>StringRef</column-ref>
     </params>
   </filter>

   <filter id="greaterRef">
     <type>greater</type>
     <params>
        <column-ref>PacketsResent</column-ref>
        <column-ref>PacketsSent</column-ref>
     </params>
   </filter>

   <filter>
     <type>or</type>
     <params>
        <filter-ref>greaterRef</filter-ref>
        <filter-ref>equalsRef</filter-ref>
     <params>
   </filter>
</filters>

Example 24-16 illustrates how to define a not equals filter, where RoleRef and StringRef are defined columns.

Example 24-16 Defining a "Not Equals" Filter for a Report

<filters>
   <filter id="equals">
     <type>equals</type>
     <params>
        <column-ref>RoleRef</column-ref>
        <column-ref>StringRef</column-ref>
     </params>
   </filter>

   <filter id = "Not">
     <type>not</type>
     <params>
        <filter-ref>equals</filter-ref>
     </params>  
   </filter>
</filters>

24.5 Using Functions to Construct a Report

Reporter functions allow mathematical calculations to be performed on data elements within the same row of the report. The supported functions are Add, Subtract, Multiply, and Divide. Function columns can then be included as parameters into other function columns.

24.5.1 Function Examples

Example 24-17 illustrates how to add columns (Attribute1 and Attribute2) and place the results into a third column (Addition).

Example 24-17 Adding Column Values and Including Results in a Different Column

<column id="AttributeID1">
  <name>Attribute1</name>
</column>

<column id="AttributeID2">
  <name>Attribute2</name>
</column>

<column id="Addition">
  <type>function</type>
  <name>Add2Columns</name>
  <header>Adding Columns</header>
  <function-name>add</function-name>
  <params>
    <column-ref>AttributeID1</column-ref>
    <column-ref>AttributeID2</column-ref>
  </params>
</column>

Example 24-18 illustrates how to subtract one column value (Attribute2) from another (Attribute1) and place the results into a third column (Subtraction).

Example 24-18 Subtracting Column Values and Including Results in a Different Column

<column id="AttributeID1">
  <name>Attribute1</name>
</column>

<column id="AttributeID2">
  <name>Attribute2</name>
</column>

<column id="Subtraction">
  <type>function</type>
  <name>Subtract2Columns</name>
  <header>Difference</header>
  <function-name>subtract</function-name>
  <params>

    <column-ref>AttributeID1</column-ref>
    <column-ref>AttributeID2</column-ref>
  </params>
</column>

Example 24-19 illustrates how to multiply column values (Attribute1 and Attribute2) place the results into a third column (Multiplication).

Example 24-19 Multiplying Column Values and Including Results in a Different Column

<column id="AttributeID1">
  <name>Attribute1</name>
</column>

<column id="AttributeID2">
  <name>Attribute2</name>
</column>

<column id="Multiplication">
  <type>function</type>
  <name>Multiply2Columns</name>
  <header>Multiply Columns</header>
  <function-name>multiply</function-name>
  <params>
    <column-ref>AttributeID1</column-ref>
    <column-ref>AttributeID2</column-ref>
  </params>
</column>

Example 24-20 illustrates how to divide one column (Attribute1) by another (Attribute2) into a third column (Division). The result of all division is a Double data type.

Example 24-20 Dividing Column Values and Including Results in a Different Column

<column id="AttributeID1">
  <name>Attribute1</name>
</column>

<column id="AttributeID2">
  <name>Attribute2</name>
</column>

<column id="Division">
  <type>function</type>
  <name>Dividing2Columns</name>
  <header>Division</header>
  <function-name>Divide</function-name>
  <params>
    <column-ref>AttributeID1</column-ref>
    <column-ref>AttributeID2</column-ref>
  </params>
</column>

24.6 Using Aggregates to Construct a Report

Reporter aggregates allow for multiple rows to be aggregated into a single value or row. Table 24-3 describes the available aggregate types.

Table 24-3 Reporter Aggregate Types

Type Description

avg

Calculate the mean value for all values in the column.

max

Return the maximum value for all values in the column.

min

Return the minimum value for all values in the column.

sum

Add all the values from a column.


24.6.1 Aggregate Examples

Sum the values in the size column

Example 24-21 Adding the Values in a Column

<column id ="SumRef">
   <type>function</type>
   <function-name>sum</function-name>
   <column-ref>size</column-ref>>
   <header>Sum</header>
</column>

Average the values in the size column

Example 24-22 Calculating the Average of Values in a Column

<column id ="AverageRef">
   <type>function</type>
   <header>Average</header>
   <function-name>avg</function-name>
   <column-ref>size</column-ref>>
</column>

Find the maximum the value in the size column

Example 24-23 Finding the Maximum Value in a Column

<column id ="MaximumRef">
   <type>function</type>
   <header>Maximum</header>
   <function-name>max</function-name>
   <column-ref>size</column-ref>>
</column>

Find the minimum the value in the size column

Example 24-24 Finding the Minimum Value in a Column

<column id ="MinimumRef">
   <type>function</type>
   <header>Minimum</header>
   <function-name>min</function-name>
   <column-ref>size</column-ref>>
</column>

24.7 Constructing Delta Functions

Many numeric attributes in the Coherence report are cumulative. These values are reset only when the resetStatistics operation is executed on the MBean. To determine the state of the system without resetting the statistics, the Reporter uses a delta function. The delta function subtracts the prior value of a column from the current value of a column and returns the difference.

The prior values for a report are stored in a map on the Reporter client. This map is keyed by the "delta key". By default, the delta key is the MBean name for the attribute. However, when one-to-one relationship does not exist between the MBean and the rows in the report, or the MBean name is subject to change between executions of the report, the delta key will be calculated using the columns provided in the <params> section.

Note:

Accuracy of Delta Functions: delta functions are only correct when the report is running as part of a report batch.

24.7.1 Delta Function Examples

Example 24-25 illustrates how to include a delta calculation of an attribute. (Assume PacketsSent is a defined column)

Example 24-25 Delta Calculation for an Attribute

<column id="DeltaPacketsSent"> 
  <type>function</type> 
  <name>PacketsSent</name> 
  <header>Delta Sent</header> 
  <function-name>delta</function-name> 
  <column-ref>PacketsSent</column-ref> 
</column>

Example 24-26 illustrates how to include a delta calculation of an attribute with an alternate delta key. (Assume PacketsSent, NodeID and TimeStamp are defined columns)

Example 24-26 Delta Calculation for an Attribute with an Alternate Delta Key

<column id="DeltaPacketsSent">
  <type>function</type>
  <name>PacketsSent</name>
  <header>Delta Sent</header>
  <function-name>delta</function-name>
  <column-ref>PacketsSent</column-ref>
  <params>
     <column-ref>NodeID</column-ref>
     <column-ref>TimeStamp</column-ref>
  </params>
</column>