Bug 62367 - HTML Report Generator: Add Graph Total Transactions per Second

Mainly contributed by  laks.martha 
Bugzilla Id: 62367

git-svn-id: https://svn.apache.org/repos/asf/jmeter/trunk@1831444 13f79535-47bb-0310-9956-ffa450edef68

Former-commit-id: 341fecb621
This commit is contained in:
Philippe Mouawad 2018-05-11 20:00:39 +00:00
parent 31cd47cac1
commit 5063b3863e
5 changed files with 265 additions and 0 deletions

View File

@ -1331,6 +1331,84 @@ function refreshTransactionsPerSecond(fixTimestamps) {
}
};
var totalTPSInfos = {
data: ${totalTPS!"{}"},
getOptions: function(){
return {
series: {
lines: {
show: true
},
points: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%H:%M:%S",
axisLabel: getElapsedTimeLabel(this.data.result.granularity),
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20,
},
yaxis: {
axisLabel: "Number of transactions / sec",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 20
},
legend: {
noColumns: 2,
show: true,
container: "#legendTotalTPS"
},
selection: {
mode: 'xy'
},
grid: {
hoverable: true // IMPORTANT! this is needed for tooltip to
// work
},
tooltip: true,
tooltipOpts: {
content: "%s at %x was %y transactions / sec"
},
colors: ["#9ACD32", "#FF6347"]
};
},
createGraph: function () {
var data = this.data;
var dataset = prepareData(data.result.series, $("#choicesTotalTPS"));
var options = this.getOptions();
prepareOptions(options, data);
$.plot($("#flotTotalTPS"), dataset, options);
// setup overview
$.plot($("#overviewTotalTPS"), dataset, prepareOverviewOptions(options));
}
};
// Total Transactions per second
function refreshTotalTPS(fixTimestamps) {
var infos = totalTPSInfos;
prepareSeries(infos.data);
if(fixTimestamps) {
fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0});
}
if(isGraph($("#flotTotalTPS"))){
infos.createGraph();
}else{
var choiceContainer = $("#choicesTotalTPS");
createLegend(choiceContainer, infos);
infos.createGraph();
setGraphZoomable("#flotTotalTPS", "#overviewTotalTPS");
$('#footerTotalTPS .legendColorBox > div').each(function(i){
$(this).clone().prependTo(choiceContainer.find("li").eq(i));
});
}
};
// Collapse the graph matching the specified DOM element depending the collapsed
// status
function collapse(elem, collapsed){
@ -1388,6 +1466,11 @@ function collapse(elem, collapsed){
refreshTransactionsPerSecond(true);
}
document.location.href="#transactionsPerSecond";
} else if (elem.id == "bodyTotalTPS") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshTotalTPS(true);
}
document.location.href="#totalTPS";
} else if (elem.id == "bodyResponseTimeVsRequest") {
if (isGraph($(elem).find('.flot-chart-content')) == false) {
refreshResponseTimeVsRequest();
@ -1471,6 +1554,9 @@ function toggleAll(id, checked){
} else if ( id == "choicesTransactionsPerSecond"){
choiceContainer = $("#choicesTransactionsPerSecond");
refreshTransactionsPerSecond(false);
} else if ( id == "choicesTotalTPS"){
choiceContainer = $("#choicesTotalTPS");
refreshTotalTPS(false);
} else if ( id == "choicesResponseTimeVsRequest"){
choiceContainer = $("#choicesResponseTimeVsRequest");
refreshResponseTimeVsRequest();

View File

@ -80,6 +80,9 @@
<li>
<a href="Throughput.html#transactionsPerSecond" onclick="$('#bodyTransactionsPerSecond').collapse('show');">Transactions Per Second</a>
</li>
<li>
<a href="Throughput.html#totalTPS" onclick="$('#bodyTotalTPS').collapse('show');">Total Transactions Per Second</a>
</li>
<li>
<a href="Throughput.html#responseTimeVsRequest" onclick="$('#bodyResponseTimeVsRequest').collapse('show');">Response Time Vs Request</a>
</li>
@ -281,6 +284,52 @@
<!-- /.panel -->
</div>
<div class="col-lg-12 portlet" id="totalTPS">
<div class="panel panel-default">
<div class="panel-heading portlet-header">
<i class="fa fa-bar-chart-o fa-fw"> </i> <span type="button" class="dropdown-toggle click-title span-title" data-toggle="collapse" href="#bodyTotalTPS" aria-expanded="true" aria-controls="bodyTotalTPS">Total Transactions Per Second</span>
<div class="pull-right">
<div class="btn-group">
<a class="btn btn-link btn-xs">
<i class="glyphicon glyphicon-resize-vertical"></i>
</a>
<button type="button" class="btn btn-link btn-xs dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-wrench"></i>
</button>
<ul class="dropdown-menu dropdown-user">
<li><a href="#totalTPS" onClick="checkAll('choicesTotalTPS');">Display all samples</a>
</li>
<li><a href="#totalTPS" onClick="uncheckAll('choicesTotalTPS');">Hide all samples</a>
</li>
<li><a href="#totalTPS" onclick="exportToPNG('flotTotalTPS', this);">Save as PNG</a></li>
</ul>
<button type="button" class="btn btn-link btn-xs dropdown-toggle" data-toggle="collapse" href="#bodyTotalTPS" aria-expanded="true" aria-controls="bodyTotalTPS">
<i class="fa fa-chevron-down"></i>
</button>
</div>
</div>
</div>
<!-- /.panel-heading -->
<div class="collapse out portlet-content" id="bodyTotalTPS">
<div class="panel-body" id="collapseTotalTPS">
<div class="flot-chart">
<div class="flot-chart-content" id="flotTotalTPS" style="float: left; width:80%;"></div>
<div style="float:left;margin-left:5px">
<p>Zoom :</p>
<div id="overviewTotalTPS" style="width:190px;height:100px;"></div>
</div>
</div>
</div>
<div class="panel-footer" id="footerTotalTPS">
<p id="legendTotalTPS" hidden></p>
<ul id="choicesTotalTPS" class="legend"></ul>
</div>
</div>
<!-- /.panel-body -->
</div>
<!-- /.panel -->
</div>
<div class="col-lg-12 portlet" id="responseTimeVsRequest">
<div class="panel panel-default">
<div class="panel-heading portlet-header">

View File

@ -161,6 +161,11 @@ jmeter.reportgenerator.graph.codesPerSecond.title=Codes Per Second
jmeter.reportgenerator.graph.codesPerSecond.exclude_controllers=true
jmeter.reportgenerator.graph.codesPerSecond.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
# Total TPS Per Second graph definition
jmeter.reportgenerator.graph.totalTPS.classname=org.apache.jmeter.report.processor.graph.impl.TotalTPSGraphConsumer
jmeter.reportgenerator.graph.totalTPS.title=Total Transactions Per Second
jmeter.reportgenerator.graph.totalTPS.property.set_granularity=${jmeter.reportgenerator.overall_granularity}
# Transactions Per Second graph definition
jmeter.reportgenerator.graph.transactionsPerSecond.classname=org.apache.jmeter.report.processor.graph.impl.TransactionsPerSecondGraphConsumer
jmeter.reportgenerator.graph.transactionsPerSecond.title=Transactions Per Second

View File

@ -0,0 +1,123 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.jmeter.report.processor.graph.impl;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.apache.jmeter.report.core.Sample;
import org.apache.jmeter.report.processor.ListResultData;
import org.apache.jmeter.report.processor.MapResultData;
import org.apache.jmeter.report.processor.TimeRateAggregatorFactory;
import org.apache.jmeter.report.processor.graph.AbstractGraphConsumer;
import org.apache.jmeter.report.processor.graph.AbstractOverTimeGraphConsumer;
import org.apache.jmeter.report.processor.graph.AbstractSeriesSelector;
import org.apache.jmeter.report.processor.graph.CountValueSelector;
import org.apache.jmeter.report.processor.graph.GroupInfo;
import org.apache.jmeter.report.processor.graph.SeriesData;
import org.apache.jmeter.report.processor.graph.TimeStampKeysSelector;
/**
* The class TotalTPSGraphConsumer provides a graph to visualize transactions
* rate per second.
*
* @since 4.1
*/
public class TotalTPSGraphConsumer extends AbstractOverTimeGraphConsumer {
private static final String STATUS_SERIES_FORMAT = "%s-%s";
private static final String SUCCESS_SERIES_SUFFIX = "success";
private static final String FAILURE_SERIES_SUFFIX = "failure";
private static final String TRANSACTION_SUCCESS_LABEL = String.format(STATUS_SERIES_FORMAT, "Transaction", SUCCESS_SERIES_SUFFIX);
private static final String TRANSACTION_FAILURE_LABEL = String.format(STATUS_SERIES_FORMAT, "Transaction", FAILURE_SERIES_SUFFIX);
/*
* (non-Javadoc)
*
* @see
* org.apache.jmeter.report.csv.processor.impl.AbstractOverTimeGraphConsumer
* #createTimeStampKeysSelector()
*/
@Override
protected TimeStampKeysSelector createTimeStampKeysSelector() {
TimeStampKeysSelector keysSelector = new TimeStampKeysSelector();
keysSelector.setSelectBeginTime(false);
return keysSelector;
}
/*
* (non-Javadoc)
*
* @see org.apache.jmeter.report.csv.processor.impl.AbstractGraphConsumer#
* createGroupInfos()
*/
@Override
protected Map<String, GroupInfo> createGroupInfos() {
Map<String, GroupInfo> groupInfos = new HashMap<>(1);
groupInfos.put(AbstractGraphConsumer.DEFAULT_GROUP,
new GroupInfo(new TimeRateAggregatorFactory(), new AbstractSeriesSelector(true) {
@Override
public Iterable<String> select(Sample sample) {
return Arrays.asList(sample.getSuccess() ? TRANSACTION_SUCCESS_LABEL : TRANSACTION_FAILURE_LABEL);
}
},
// We include Transaction Controller results
new CountValueSelector(false), false, false));
return groupInfos;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.jmeter.report.csv.processor.impl.AbstractOverTimeGraphConsumer
* #setGranularity(long)
*/
@Override
public void setGranularity(long granularity) {
super.setGranularity(granularity);
// Override the granularity of the aggregators factory
((TimeRateAggregatorFactory) getGroupInfos().get(AbstractGraphConsumer.DEFAULT_GROUP).getAggregatorFactory())
.setGranularity(granularity);
}
@Override
protected void initializeExtraResults(MapResultData parentResult) {
super.initializeExtraResults(parentResult);
String[] seriesLabels = new String[]{
TRANSACTION_SUCCESS_LABEL, TRANSACTION_FAILURE_LABEL
};
initializeSeries(parentResult, seriesLabels);
}
private void initializeSeries(MapResultData parentResult, String[] series) {
ListResultData listResultData = (ListResultData) parentResult.getResult("series");
for (int i = 0; i < series.length; i++) {
listResultData.addResult(create(series[i]));
}
}
private MapResultData create(String serie) {
GroupInfo groupInfo = getGroupInfos().get(AbstractGraphConsumer.DEFAULT_GROUP);
SeriesData seriesData = new SeriesData(groupInfo.getAggregatorFactory(),
groupInfo.enablesAggregatedKeysSeries(), false,
groupInfo.enablesOverallSeries());
return createSerieResult(serie, seriesData);
}
}

View File

@ -130,6 +130,7 @@ this behaviour, set <code>httpclient.reset_state_on_thread_group_iteration=false
<h3>Report / Dashboard</h3>
<ul>
<li><bug>62243</bug>Dashboard : make option "<code>--forceDeleteResultFile</code>"/"<code>-f</code>" option delete folder referenced by "<code>-o</code>" option</li>
<li><bug>62367</bug>HTML Report Generator: Add Graph Total Transactions per Second. Contributed mainly by Martha Laks (laks.martha at gmail.com)</li>
</ul>
<h3>General</h3>
@ -245,6 +246,7 @@ this behaviour, set <code>httpclient.reset_state_on_thread_group_iteration=false
<li>Imane Ankhila (iankhila at ahlane.net)</li>
<li>jffagot05 (jffagot05 at gmail.com)</li>
<li>Perze Ababa (perze.ababa at gmail.com)</li>
<li>Martha Laks (laks.martha at gmail.com)</li>
</ul>
<p>We also thank bug reporters who helped us improve JMeter.</p>
<p>