JBoss ON CLI resource proxy returns value of "?" for calltime metrics

Solution Verified - Updated

Environment

  • Red Hat JBoss Operations Network (ON) 3.2
  • JBoss ON command-line interface (CLI)
  • Using a resource proxy's get<calltime metric name>() method

Issue

  • Print a report of call time metrics

  • displayValue of ? when invoking:

      var apacheVHost = ProxyFactory.getResource(10010);
      pretty.print(apacheVHost.HTTPResponseTime);
    
  • Printing HTTP Response Time metrics for Apache Virtual Host resource

  • Resource proxy returned by ProxyFactory returns ? as calltime metric values

Resolution

As calltime metric data is always historic, you will need to use the This content is not included.CallTimeDataManagerRemote.findCallTimeDataForResource remote API or CLI method.

The following CLI script provides an example of exporting specific calltime metric data for all resources of a specified type for the last 30 days and displaying it in a CSV format:

/*
 * To the extent possible under law, Red Hat, Inc. has dedicated all copyright 
 * to this software to the public domain worldwide, pursuant to the CC0 Public 
 * Domain Dedication. This software is distributed without any warranty.  
 * 
 * See <http://creativecommons.org/publicdomain/zero/1.0/>.
 * 
 * This script is an example only and demonstrates how to retrieve historical 
 * metric data for a server resource and write it to a file using the built 
 * in JBoss ON CLI exporter command.
 * 
 */

/**
 * Display a usage message
 */
function usage() {
    println("Usage: getCalltime.js <type> <plugin> <calltime name>");
    println("");
    println("<type> is the resource type name");
    println("<plugin> is the resource type's plug-in name");
    println("<calltime name> is the display name of the call time measurement");
    println("");
    println("Example:");
    println("   getCalltime.js \"Web Runtime\" JBossAS7 \"Response Time\"");
}
​
// we expect 3 arguments
​if ( args.length != 3 ) {
    usage();
    throw "Missing required arguments.";
​}

​var resourceTypeName = args[0]; // "Web Runtime"
var resourceTypePlugin = args[1]; // "JBossAS7"
var metricDisplayName = args[2]; // "Response Time"

// define the date/time range
var endDate = new Date(); // now
var startDate = new Date(endDate.getTime() - 30*24*3600*1000); // 30 days ago

// get the resource type for which metrics will be retrieved
var resourceType = ResourceTypeManager.getResourceTypeByNameAndPlugin(resourceTypeName, resourceTypePlugin); // type name and plug-in

// retrieve the calltime measurement definition named metricDisplayName for the retrieved resourceType
var measurementDefCriteria = new MeasurementDefinitionCriteria();
measurementDefCriteria.addFilterResourceTypeId(resourceType.getId()); // target resource type
measurementDefCriteria.addFilterDisplayName(metricDisplayName); // the metric definition's display name
measurementDefCriteria.setStrict(true); // use strict name matching
var metricDef = MeasurementDefinitionManager.findMeasurementDefinitionsByCriteria(measurementDefCriteria).get(0);

// get target resources using retrieved resourceType
var resourceCriteria = ResourceCriteria();
resourceCriteria.addFilterResourceTypeId(resourceType.getId()); // target resource type
var resources = ResourceManager.findResourcesByCriteria(resourceCriteria);

// print the data in CSV format
println("\"Resource Name\",\"Resource Id\",\"Call Destination\",\"Count\",\"Minimum\",\"Maximum\",\"Average\",\"Total Time\"");

// iterate through the list of resources
for (var iRes = 0; iRes < resources.size(); iRes++) {
    var resource = resources.get(iRes);
    // we set this to 0 because we only want to print if the actual calltime metric is found
    var scheduleId = 0;

    /*
     * This is a bit of a workaround. To get call time data, we must 
     * have a schedule id. But because there is no way to simply get 
     * a schedule id for a specific measurement based on its 
     * measurement definition and resource, we must get all the 
     * schedules for the target resource and then iterate through all 
     * the schedules until we find one that matches the measurement 
     * definition we care about.
     */
    var scheduleIdCriteria = new MeasurementScheduleCriteria();
    scheduleIdCriteria.addFilterResourceId(resource.getId());
    scheduleIdCriteria.setPageControl(PageControl.getUnlimitedInstance());
    // this will be all the schedules for this resource
    var schedules = MeasurementScheduleManager.findSchedulesByCriteria(scheduleIdCriteria);

    // now go through the list of returned schedules
    for (var iSchedule = 0; iSchedule < schedules.size(); iSchedule++) {
        var schedule = schedules.get(iSchedule);
        // only set scheduleId if this schedule matches the measurement definition returned for metricDef above
        if (schedule.getDefinition().getId() == metricDef.getId()) {
            scheduleId = schedule.getId();
            // as soon as we find that match, no need to continue looking
            break;
        }
    }

    // we can only enter this block if a schedule id match was found
    if (scheduleId != 0) {
        // this is where we actually read the call time metric data for this resource
        var dataCompositeList = CallTimeDataManager.findCallTimeDataForResource(scheduleId, startDate, endDate, PageControl.getUnlimitedInstance());
        for (var iDataCompositeList = 0; iDataCompositeList < dataCompositeList.size(); iDataCompositeList++) {
            var dataComposite = dataCompositeList.get(iDataCompositeList);
            print("\"" + resource.getName() + "\","); // Resource Name
            print(resource.getId() + ","); // Resource Id
            print("\"" + dataComposite.getCallDestination() + "\","); // Call Destination
            print(dataComposite.getCount() + ","); // Count
            print(dataComposite.getMinimum() + ","); // Minimum
            print(dataComposite.getMaximum() + ","); // Maximum
            print(dataComposite.getAverage() + ","); // Average
            println(dataComposite.getTotal()); // Total Time
        }
    }
}

For example, to display CSV formatted output of the HTTP Response Time calltime metric for all Apache Virtual Host resources, you can invoke the script using a command similar to:

 rhq-remoting-cli/bin/rhq-cli.sh -u rhqadmin -p rhqadmin -s jboss-on.example.com -t 7080 -f "$PWD"/getCalltime.js "Apache Virtual Host" Apache "HTTP Response Time"

Root Cause

The metric attribute and get method exposed by the CLI's resource proxy attempts to retrieve live metric data directly from the resource. As calltime metric data is not live, an empty value is returned. This empty value is displayed as ? indicating it is undefined.

This content is not included.Red Hat Bugzilla 1169543 has been captured to investigate this issue further. It is not clear at this time if the methods and attributes for metrics of type calltime should not be exposed or if these methods should include additional parameters allowing the retrieval of historic data.

Diagnostic Steps

  • Is a CLI resource proxy being used? A resource proxy object is generated using myResource = ProxyFactory.getResource(resId). If not, this issue does not apply.

  • Is a metric attribute being read from a resource proxy object either directly or using its get method? For example:

      var myApacheVHost = ProxyFactory.getResource(myResource.getId());
      var rtMetric = myApacheVHost.getHTTPResponseTime();
    

    Is the metric of type calltime? If so, this issue applies.

SBR
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.