mirror of https://github.com/apache/jmeter.git
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:
parent
31cd47cac1
commit
5063b3863e
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Reference in New Issue