Overview:
In this post, Lets see how we can use Beanshell Listener / JSR223 Listener in JMeter to send the result, the way we want, to a database. The below approach will work like Backend Listener of JMeter to post the sampler results into InfluxDB.
Sample Result API:
To write the results the way we want, We will be using the SampleResult API in the listener.
Lets assume we are interested in the sample label, no of samples executed, response time, status and time-stamp the sample occurred.
- sampleResult.getSampleLabel() – gives the sample name which just occurred.
- sampleResult.getSampleCount() – no of samples
- sampleResult.getTime() – duration of the sample
- sampleResult.getResponseCode() – response code
- sampleResult.getTimeStamp() – timestamp
- sampleResult.isSuccessful() – true if it is success; false otherwise.
InfluxDB:
I would be using InfluxDB as backend to store the data using its HTTP API.
Check here for more information.
At this time of this post, v0.12 is latest. Please check InfluxDB site for the latest versions installation steps as the above URLs might not work later.
Ensure that your InfluxDB is up and running. You should be able to access the admin interface on the port 8083. http://[ipaddress]:8083
Create a database ‘demo’ with this query: CREATE DATABASE “demo”.
JMeter Test Plan:
We would be creating a very simple test plan as shown below. I am just using a ‘Dummy Sampler’ – changed the label names.
JSR223 Listener:
I use JSR223 Listener with Groovy. If you do not have groovy jar, download it from here and place it in %JMETER_HOME%/lib folder. You can also use Beanshell listener for this purpose. JMeter comes with all the required dependencies for beanshell.
In this listener we would be accessing sampleResult API directly to get the sample metrics which just occurred.
InfluxDB HTTP API interface would expect the data in the below format. So build the result string accordingly.
samples,label=lbl,status=status count=count,duration=duration,responsecode=rc timestamp
Add below code in the JSR223 Listener.
result = new StringBuilder();
status = "Failure";
if (sampleResult.isSuccessful())
status = "Success";
//Expected format to post the result
//samples,label=lbl,status=status count=count,duration=duration,responsecode=rc timestamp
result.append("samples,") //samples is the table name in InfluxDB which we will create at run time.
.append("label=")
.append(escapeValue(sampleResult.getSampleLabel()))
.append(",status=")
.append(status)
.append(" ")
.append("count=")
.append(sampleResult.getSampleCount())
.append(",duration=")
.append(sampleResult.getTime())
.append(",responsecode=")
.append(sampleResult.getResponseCode())
.append(" ")
.append(sampleResult.getTimeStamp())
.append("000000");
The above code will build the string to post the data. However we need to escape “,”, ” “, “=” in the string as these have some meaning in InfluxDB query.
//Escape the string values before posting the data
String escapeValue(String val) {
val = val.replaceAll(",", "\\\\,")
.replaceAll(" ", "\\\\ ")
.replaceAll("=", "\\\\=")
.trim();
return val;
}
Lets add the function which will post the data to influxDB.
// Post the result to influxDB
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.util.EntityUtils;
void PostMeasurement(String metric) {
def httpclient = new DefaultHttpClient(new BasicHttpParams());
def httpPost = new HttpPost();
//URL format : http://[ipaddress]:[port]/write?db=[database]
httpPost.setURI(new URI("http://[ipaddress]:8086/write?db=demo"));
log.info("Result : " + metric);
httpPost.setEntity(new StringEntity(metric));
HttpResponse response = httpclient.execute(httpPost);
EntityUtils.consumeQuietly(response.getEntity());
}
Thats it. Now add this line to call the function which posts the data.
PostMeasurement(result.toString());
Run the test for couple of times. Now query the InfluxDB using its Admin interface. “select * from samples” on the demo Database will show the results as shown below.
If you are still facing issues in sending the data to InfluxDB - Check this post to troubleshoot.
Summary:
Without using any plugins/backend listener/extending jmeter functionilities using its interface, We saw how to write the results in DB. This approach might be slow if you do not have any timers in the test plan. You can modify the approach slightly to post the data asynchronously. We can also modify the listener to post the data once in certain interval (say 30 seconds) instead of posting for every sample which will help with performance.
Happy testing 🙂