Adding custom counters to reports

When you want to monitor the specific requirement, you can add custom counters to performance report by using the custom code. After running tests, the results from the custom counters are automatically aggregated in the same way that the default performance testing counters.

Starting from 10.1.0, you can view and monitor the counter information generated by the custom code on a graph when the custom code starts in the test run.

After running tests, you can view the custom counter in the report. You can also view the custom counter information on a different page by creating a custom report. For more information about customizing the report, see related links.

The Javadoc for the test execution services interfaces and classes can be accessed from the product by clicking Help > Help Contents > Rational Functional Tester API Reference.

You can add the following custom code in your test to create a custom counter in a report.

package test;

import org.eclipse.hyades.test.common.event.VerdictEvent;

import com.ibm.rational.test.lt.kernel.services.ITestExecutionServices;
import com.ibm.rational.test.lt.kernel.services.stats.CountAggregationLevel;
import com.ibm.rational.test.lt.kernel.services.stats.CounterUnits;
import com.ibm.rational.test.lt.kernel.services.stats.ICounterFolder;
import com.ibm.rational.test.lt.kernel.services.stats.ICounterRegistry;
import com.ibm.rational.test.lt.kernel.services.stats.IStatisticsManager2;
import com.ibm.rational.test.lt.kernel.services.stats.IValueCounter;
import com.ibm.rational.test.lt.kernel.services.stats.ValueAggregationLevel;

import database.DatabaseAccess;
import database.TransactionResult;

public class DatabaseStats implements com.ibm.rational.test.lt.kernel.custom.ICustomCode2 {

	private static boolean registerDone;
	
	/**
	 * This method declares the counters that will be produced during execution.
	 * Declaring counters is optional, but it allows to customize some of their
	 * attributes, such as the label and unit, and what level of statistical information
	 * will be available in reports.
	 */
	private static synchronized void registerCounters(ICounterRegistry registry) {
		if (registerDone) return;
		registry.path("Database", "Transaction", "Attempts")
			.count()
			.aggregationLevel(CountAggregationLevel.RATE_RANGE)
			.label("Started Transactions")
			.unit("transactions")
			.register();
		
		registry.path("Database", "Transaction", "Commits")
			.verificationPoint()
			.label("Transaction Commits VP")
			.register();
		
		registry.path("Database", "Transaction", "Response Time", "Network")
			.value()
			.aggregationLevel(ValueAggregationLevel.RANGE)
			.unit(CounterUnits.MILLISECONDS)
			.register();
			
		registry.path("Database", "Transaction", "Response Time", "Commit")
			.value()
			.aggregationLevel(ValueAggregationLevel.DISTRIBUTION)
			.unit(CounterUnits.MILLISECONDS)
			.register();
		
		registry.path("Database", "Error")
			.text()
			.label("Database Error Message")
			.register();
		registerDone = true;
	}
	
	private DatabaseAccess database = DatabaseAccess.INSTANCE;
	
	/**
	 * This custom code adds a record in database. It produces a couple of counters,
	 * such as the database transaction attempts, successes/failures, and response time.
	 */
	public String exec(ITestExecutionServices tes, String[] args) {
		String product = args.length> 0 ? args[0] : "Default";
		IStatisticsManager2 mgr = tes.getStatisticsManager2();
		registerCounters(mgr.registry());
		
		database.startTransaction();
		mgr.getCountCounter("Database", "Transaction", "Attempts").increment();

		database.executeQuery("INSERT INTO TABLE Purchases VALUES('" + product + "', 1000)");
		TransactionResult result = database.commit();
		
		mgr.getVerificationPointCounter("Database", "Transaction", "Commits")
			.increment(result.isSuccess() ? VerdictEvent.VERDICT_PASS : VerdictEvent.VERDICT_FAIL);
		if (!result.isSuccess()) {
			mgr.getTextCounter("Database", "Error").addMeasurement(result.getErrorMessage());
		}
		
		ICounterFolder times = mgr.getFolder("Database", "Transaction", "Response Time");
		times.getValueCounter("Network").addMeasurement(result.getNetworkTime());
		times.getValueCounter("Commit").addMeasurement(result.getCommitTime());
		
		IValueCounter value = tes.getStatisticsManager2().getValueCounter("MyStats", "Value");
		value.addMeasurement(System.nanoTime() % 2000);
		
		return null;
	}

}