Statistics Capture - logginghub/jbombardier GitHub Wiki
Statistics Capture is a JBombardier feature which allows you to gather external information during your test execution. It is a very open and flexible feature, allowing you to bring pretty much anything into the test, and then recorded in the test reports.
Here are some examples to get you thinking about how it might come in handy:
- Capturing GC events during test execution, so you can attempt to correlate them to performance spikes or just to see how much garbage you are creating over time
- Grabbing data from a JMX source - for example extracting queue sizes from an MQ to see how big your queues are growing during the test
- Extracting events from a LoggingHub event stream to capture any WARNING or SEVERE events that occur during the test run that might indicate problems during the test
- Scraping the results of a web admin interface in your system to extract some custom information
How-to
We'll cover a few different options - there are a few out-of-the-box captures, and then we'll explain how to build your own from scratch.
- Extracting data from events from LoggingHub
- Extracting data via JMX
- Building your own capture plugin to grab some data via HTTP
There are a few concepts common to all captures.
Capture Path - this is how you differentiate between the different things you might capture in a test. You can use the path to build up a hierarchy of related capture values. For example
- /mytest/jmx/queueSizes/mainMQ
- /mytest/jmx/queueSizes/failoverMQ
- /mytest/logginghub/gc/appserver
- /mytest/logginghub/gc/cacheserver
Capture Time - the time the event was captured
Capture Value - a string that represents the value that was captured
Logging Hub
JBombardier has a built in capture plugin for logging hub. Here is an example configuration:
<jbombardier>
<hubCapture hub="localhost:15000">
<pattern path="/mytest/logginghub/gc/{sourceHost}/{sourceApplication}" pattern="GC pause {time} ms collected {size} kb - [what]" values="time,size"/>
</hubCapture>
</jbombardier>
This will connect to the hub at localhost:15000 and generate events every time it sees the standard LoggingHub GC event pattern. It will create two bits of data for each event - one for the length of time reported from the collector, and one of the number of bytes of garbage collected.
You can add multiple <pattern .../> elements if you want to extract more than one pattern from the same hub. If you have multiple hubs, you can add multiple <hubCapture .../> elements as well.
If you have multiple application instances spread across multiple machines, you'll need to include something in the path to help differentiate results from different sources. You can use this by using {tokens in curly braces} within the path. Here is a list of the most helpful elements from the log event you can use to differentiate results:
- {sourceHost}
- {sourceAddress}
- {sourceApplication}
- {pid}
JMX
<jbombardier>
<jmxCapture connectionPoints="localhost:12345,localhost:12346" username="jmxUser" password="jmxPassword">
<jmx path="/mytest/jmx/{target}/threads" objectName="java.lang:type=Threading" attribute="TotalStartedThreadCount"/>
</jmxCapture>
</jbombardier>
This configuration will connect to two JMX endpoints and retrieve the value of TotalStartedThreadCount from the MBean java.lang:type=Threading.
In order to tell the difference between the values captured from each endpoint, it will replace {target} in the path with the host:port of each connection it makes.
Building your own
Lets try and build a quick statistics capture plugin to periodically extract data from a URL.
First up we use the statisticsCapture element in the configuration to provide our custom class:
<jbombardier>
<statisticsCapture className="com.myco.WebStatisticsCapture" properties="url=http://localhost:12345/stats/,interval=10 seconds" />
</jbombardier>
Lets create that class next - you need to implement the StatisticProvider interface.
public class WebStatisticsCapture implements StatisticProvider {
@Override public void configure(Metadata properties) {}
@Override public void start() {}
@Override public void stop() {}
@Override public void addDestination(Destination<CapturedStatistic> destination) {}
@Override public void removeDestination(Destination<CapturedStatistic> destination) {}
}
Check the javadoc for the interface for the full details - we'll be taking a quick short cut and extend BaseStatisticCapture instead. This provides some basic helpers that are especially useful for periodic capture.
public class WebStatisticsCapture extends BaseStatisticCapture {
private String url;
@Override public void configure(Metadata properties) {
setDelay(TimeUtils.parseInterval(properties.getString("interval", "10 seconds")));
this.url = properties.getString("url");
}
@Override protected void doCapture() {
String result = FileUtils.get(url);
// Do whatever you need to extract the interesting data from the page
String extractedValue = scrapeValue(result);
CapturedStatistic capturedStatistic = new CapturedStatistic(System.currentTimeMillis(), "/myapp/web/result", extractedValue);
send(capturedStatistic);
}
}
Hopefully there shouldn't be too many surprises here - in the configure method you extract whatever variables you need from the Metadata instance (that has been filled with the data from the properties element in the XML configuration). We pass the value of interval through a helper class to convert it in the number of milliseconds between each request, and pass that down to the base class as well so it can correctly configure its timer.
In the doCapture method, we use a utility class to pull the data from the url into a string, extract out whatever data you want (this is up to you!) and then build a CapturedStatistic and send it to the JBombardier console via the base class' helper method.