Running Tabular Reports with Coherence 12.1.3 Reporter

Overview 

With the latest release of Coherence 12.1.3, we introduced the Coherence JVisualVM Plug-in as part of the product. As part of the internal development of the plug-in, we needed a way of running "Reporter" reports and retrieving the output directly from the operation return value.  The current runReport operation (which is useful for writing out reports to disk) takes in a report name and then writes the output to the filesystem using the OutputPath defined on the MBean.

Based upon this requirement, we introduced the runTabularReport operation on the Reporter MBean which takes either a report name or report XML and returns a TabularData object containing the report output. We exposed this on the MBean as we knew this would be useful for customers.

MBeans 

The following operations were added in 12.1.3

  • runTabularReport(String sReportFile)
  • runTabularGroupReport(String sReportName, Map mapXmlReports)

We are going to focus on the runTabularReport which is the easiest to understand and use.

Example 

Startup JVisualVM and connect to a JMX enabled cluster. Select the Reporter MBean and select one of the nodes. Enter the following report name as an argument and click runTabularReport. (Make sure you have at least one cache defined, otherwise null will be returned).

  • reports/report-cache-size.xml 

 The following will be displayed. If you have more than one cache then you can scroll through the results of the report.

 To view the full list of reports available out of the box you can issue the following command against coherence.jar.

 timmiddleton$ jar tvf coherence.jar | grep reports
     0 Thu Apr 03 14:49:54 WST 2014 reports/
  2272 Thu Apr 03 14:49:52 WST 2014 reports/report-all.xml
 17745 Thu Apr 03 14:49:52 WST 2014 reports/report-cache-effectiveness.xml
  2629 Thu Apr 03 14:49:52 WST 2014 reports/report-cache-size.xml
  2152 Thu Apr 03 14:49:52 WST 2014 reports/report-flashjournal.xml
  1672 Thu Apr 03 14:49:52 WST 2014 reports/report-group.xml
  1368 Thu Apr 03 14:49:52 WST 2014 reports/report-management.xml
  4652 Thu Apr 03 14:49:52 WST 2014 reports/report-memory-status.xml
  4541 Thu Apr 03 14:49:52 WST 2014 reports/report-network-health-detail.xml
  7743 Thu Apr 03 14:49:52 WST 2014 reports/report-network-health.xml
  1656 Thu Apr 03 14:49:52 WST 2014 reports/report-node.xml
  2638 Thu Apr 03 14:49:52 WST 2014 reports/report-persistence-detail.xml
  2929 Thu Apr 03 14:49:52 WST 2014 reports/report-persistence.xml
  4270 Thu Apr 03 14:49:52 WST 2014 reports/report-proxy.xml
  1715 Thu Apr 03 14:49:52 WST 2014 reports/report-ramjournal.xml
  4588 Thu Apr 03 14:49:52 WST 2014 reports/report-service.xml
 18473 Thu Apr 03 14:49:52 WST 2014 reports/report-web-cache-overflow.xml
 18456 Thu Apr 03 14:49:52 WST 2014 reports/report-web-cache-sessions.xml
  1771 Thu Apr 03 14:49:52 WST 2014 reports/report-web-group.xml
  4625 Thu Apr 03 14:49:52 WST 2014 reports/report-web-service.xml
 16907 Thu Apr 03 14:49:52 WST 2014 reports/report-web-sessions.xml
  3856 Thu Apr 03 14:49:52 WST 2014 reports/report-web.xml

This is well and good, but the main reason you would want to do this is to directly run a report given a MBeanServer connection and retrieve the results.  

Programatic Access to Reports Output 

All you need to run a report is an MBeanServer connection. This can be obtained via either using the MBeanHelper as per below, or there are a couple of code examples out there you could utilise such as here or here. (Thanks to Ben and Aleks)

Then you can invoke the runTabularReport using that connection.

In my example below, i'm doing the following:

  1. Setting system properties to ensure we have JMX management set
  2. Connect to / create a Coherence Cluster
  3. Get the MBeanServer using the helper
  4. Create some caches and insert data 
  5. Run the report
  6. Navigate the TabularData and output the values.

The full code example is below. 

import com.tangosol.net.CacheFactory;
import com.tangosol.net.Cluster;
import com.tangosol.net.NamedCache;
import com.tangosol.net.management.MBeanHelper;

import java.util.Collection;
import java.util.Set;

import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;

import javax.management.openmbean.TabularData;

public class ReporterExample
    {
    public static void main(String[] args)
            throws InstanceNotFoundException, MalformedObjectNameException, 
                   ReflectionException, MBeanException
        {
        // enable management before we start/join a cluster
        System.setProperty("tangosol.coherence.management", "all");
        System.setProperty("tangosol.coherence.log.level", "2");

        Cluster     cluster = CacheFactory.ensureCluster();
        MBeanServer server  = MBeanHelper.findMBeanServer();

        // create caches and add some data
        NamedCache nc1 = CacheFactory.getCache("dist-tim1");
        NamedCache nc2 = CacheFactory.getCache("dist-tim2");

        nc1.put("key1", "value1");
        nc2.put("key1", "value1");

        // get the local member to run the report on
        int nLocalMemberId = cluster.getLocalMember().getId();

        TabularData reportData = (TabularData) server.invoke(
              new ObjectName("Coherence:type=Reporter,nodeId=" + nLocalMemberId), 
                             "runTabularReport",
                             new Object[] {"reports/report-cache-size.xml"},
                             new String[] {"java.lang.String"});

        // navigate the data
        if (reportData != null)
            {
            Set<?> setKeys = reportData.keySet();

            if (setKeys.size() > 0)
                {
                // loop through each key, which is actually the row of data

                for (Object oKey : setKeys)
                    {
                    // get the columns as an array
                    Object[] aoColumns = ((Collection<Object>) oKey).toArray();

                    for (int i = 0; i < aoColumns.length; i++)
                        {
                        System.out.print(aoColumns[i].toString() + "\t");
                        }

                    System.out.println();
                    }
                }

            }
        }
    }

Running this for my cluster and two caches gives the following output:

 Oracle Coherence Version 12.1.3.0.0 
 Grid Edition: Development mode
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

1  0  DistributedCache  dist-tim  100000.0  3.1776896E7  30.3048095703125  317.76896	
2  0  DistributedCache  dist-tim1 1.0       224.0        2.13623046875E-4  224.0	
3  0  DistributedCache  dist-tim2 1.0       224.0        2.13623046875E-4  224.0	

You can also pass in report XML rather than an actual report file, so you can build up your reporter XML on the fly or manipulate the XML before you run it, e.g. parameterise it!

If you have a report group, it can be a little trickier to navigate,  but here is some guidance. Execute the specified report file or report XML defined in the sReport argument. If the report XML file or XML content defines a single report, the returned TabularData will have a CompositeData for each row of values from the report. It will also include a rowId attribute for indexing. For example:

        TabularData(sReportFile) =
                TabularData[ CompositeData { attribute1 -> value1,
                                             attribute2 -> value2,
                                             rowId      -> 1},
                             CompositeData { attribute1 -> value1,
                                             attribute2 -> value2,
                                             rowId      -> 2} ]
    

If the specified file or XML content defines a report group, the returned TabularData will have a single CompositeData with report-names as keys and TabularDatas of the reports as values. For example:

        TabularData[ CompositeData { report1 -> TabularData(report1),
                                 report2 -> TabularData(report2) } ]
    

Enjoy. 



Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Oracle Coherence, the market leading in-memory datagrid product.
Stay Connected...

Search

Archives
« March 2015
SunMonTueWedThuFriSat
1
2
3
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    
       
Today