diff --git a/bin/report-template/content/js/dashboard-commons.js b/bin/report-template/content/js/dashboard-commons.js index 010ba22b17..91b661dd06 100644 --- a/bin/report-template/content/js/dashboard-commons.js +++ b/bin/report-template/content/js/dashboard-commons.js @@ -73,6 +73,13 @@ function getElapsedTimeLabel(granularity) { return "Elapsed Time (granularity: " + formatDuration(granularity) + ")"; } +/* + * Gets axis label for the specified granularity + */ +function getConnectTimeLabel(granularity) { + return "Connect Time (granularity: " + formatDuration(granularity) + ")"; +} + //Get the property value of an object using the specified key //Returns the property value if all properties in the key exist; undefined //otherwise. diff --git a/bin/report-template/content/js/graph.js.fmkr b/bin/report-template/content/js/graph.js.fmkr index f222803e5e..efda6acca8 100644 --- a/bin/report-template/content/js/graph.js.fmkr +++ b/bin/report-template/content/js/graph.js.fmkr @@ -402,7 +402,7 @@ var syntheticResponseTimeDistributionInfos = { return yval + " " + label; } }, - colors: ["green", "yellow", "orange", "red"] + colors: ["#9ACD32", "yellow", "orange", "#FF6347"] }; }, createGraph: function() { @@ -806,6 +806,83 @@ function refreshLatenciesOverTime(fixTimestamps) { } }; +var connectTimeOverTimeInfos = { + data: ${connectTimeOverTime!"{}"}, + getOptions: function() { + return { + series: { + lines: { + show: true + }, + points: { + show: true + } + }, + xaxis: { + mode: "time", + timeformat: "%H:%M:%S", + axisLabel: getConnectTimeLabel(this.data.result.granularity), + axisLabelUseCanvas: true, + axisLabelFontSizePixels: 12, + axisLabelFontFamily: 'Verdana, Arial', + axisLabelPadding: 20, + }, + yaxis: { + axisLabel: "Average Connect Time in ms", + axisLabelUseCanvas: true, + axisLabelFontSizePixels: 12, + axisLabelFontFamily: 'Verdana, Arial', + axisLabelPadding: 20, + }, + legend: { + noColumns: 2, + show: true, + container: '#legendConnectTimeOverTime' + }, + selection: { + mode: 'xy' + }, + grid: { + hoverable: true // IMPORTANT! this is needed for tooltip to + // work + }, + tooltip: true, + tooltipOpts: { + content: "%s : at %x Average connect time was %y ms" + } + }; + }, + createGraph: function () { + var data = this.data; + var dataset = prepareData(data.result.series, $("#choicesConnectTimeOverTime")); + var options = this.getOptions(); + prepareOptions(options, data); + $.plot($("#flotConnectTimeOverTime"), dataset, options); + // setup overview + $.plot($("#overviewConnectTimeOverTime"), dataset, prepareOverviewOptions(options)); + } +}; + +// Connect Time Over Time +function refreshConnectTimeOverTime(fixTimestamps) { + var infos = connectTimeOverTimeInfos; + prepareSeries(infos.data); + if(fixTimestamps) { + fixTimeStamps(infos.data.result.series, ${(timeZoneOffset?c)!0}); + } + if(isGraph($("#flotConnectTimeOverTime"))) { + infos.createGraph(); + }else { + var choiceContainer = $("#choicesConnectTimeOverTime"); + createLegend(choiceContainer, infos); + infos.createGraph(); + setGraphZoomable("#flotConnectTimeOverTime", "#overviewConnectTimeOverTime"); + $('#footerConnectTimeOverTime .legendColorBox > div').each(function(i){ + $(this).clone().prependTo(choiceContainer.find("li").eq(i)); + }); + } +}; + var responseTimeVsRequestInfos = { data: ${responseTimeVsRequest!"{}"}, getOptions: function() { @@ -1189,11 +1266,16 @@ function collapse(elem, collapsed){ refreshBytesThroughputOverTime(true); } document.location.href="#responseTimesOverTime"; - } else if (elem.id == "bodyLantenciesOverTime") { + } else if (elem.id == "bodyLatenciesOverTime") { if (isGraph($(elem).find('.flot-chart-content')) == false) { refreshLatenciesOverTime(true); } document.location.href="#latenciesOverTime"; + } else if (elem.id == "bodyConnectTimeOverTime") { + if (isGraph($(elem).find('.flot-chart-content')) == false) { + refreshConnectTimeOverTime(true); + } + document.location.href="#connectTimeOverTime"; } else if (elem.id == "bodyResponseTimeDistribution") { if (isGraph($(elem).find('.flot-chart-content')) == false) { refreshResponseTimeDistribution(); @@ -1277,6 +1359,9 @@ function toggleAll(id, checked){ } else if ( id == "choicesLatenciesOverTime"){ choiceContainer = $("#choicesLatenciesOverTime"); refreshLatenciesOverTime(false); + } else if ( id == "choicesConnectTimeOverTime"){ + choiceContainer = $("#choicesConnectTimeOverTime"); + refreshConnectTimeOverTime(false); } else if ( id == "choicesResponseTimePercentiles"){ choiceContainer = $("#choicesResponseTimePercentiles"); refreshResponseTimePercentiles(); diff --git a/bin/report-template/content/pages/OverTime.html.fmkr b/bin/report-template/content/pages/OverTime.html.fmkr index f189b7b4ca..9c752d516c 100644 --- a/bin/report-template/content/pages/OverTime.html.fmkr +++ b/bin/report-template/content/pages/OverTime.html.fmkr @@ -78,11 +78,15 @@
  • - + Latencies Over Time
  • - +
  • + + Connect Time Over Time + +
  • @@ -262,7 +266,7 @@
    - Latencies Over Time + Latencies Over Time
  • Save as PNG
  • - -
    +
    @@ -306,6 +310,55 @@
    + +
    +
    +
    + + Connect Time Over Time +
    + +
    +
    + +
    +
    +
    +
    +
    +

    Zoom :

    +
    +
    +
    +
    + +
    + + +
    + +
    +
    diff --git a/bin/reportgenerator.properties b/bin/reportgenerator.properties index f7dd465482..77649def4f 100644 --- a/bin/reportgenerator.properties +++ b/bin/reportgenerator.properties @@ -100,6 +100,11 @@ jmeter.reportgenerator.graph.latenciesOverTime.classname=org.apache.jmeter.repor jmeter.reportgenerator.graph.latenciesOverTime.title=Latencies Over Time jmeter.reportgenerator.graph.latenciesOverTime.property.set_granularity=${jmeter.reportgenerator.overall_granularity} +# Connect Time Over Time graph definition +jmeter.reportgenerator.graph.connectTimeOverTime.classname=org.apache.jmeter.report.processor.graph.impl.ConnectTimeOverTimeGraphConsumer +jmeter.reportgenerator.graph.connectTimeOverTime.title=Connect Time Over Time +jmeter.reportgenerator.graph.connectTimeOverTime.property.set_granularity=${jmeter.reportgenerator.overall_granularity} + # Response Time Vs Request graph definition jmeter.reportgenerator.graph.responseTimeVsRequest.classname=org.apache.jmeter.report.processor.graph.impl.ResponseTimeVSRequestGraphConsumer jmeter.reportgenerator.graph.responseTimeVsRequest.title=Response Time Vs Request diff --git a/src/core/org/apache/jmeter/report/core/Sample.java b/src/core/org/apache/jmeter/report/core/Sample.java index dac6c78ece..4c2e656c46 100644 --- a/src/core/org/apache/jmeter/report/core/Sample.java +++ b/src/core/org/apache/jmeter/report/core/Sample.java @@ -234,6 +234,15 @@ public class Sample { public long getLatency() { return getData(long.class, CSVSaveService.CSV_LATENCY).longValue(); } + + /** + * Gets the connect time stored in the sample. + * + * @return the connect time stored in the sample + */ + public long getConnectTime() { + return getData(long.class, CSVSaveService.CSV_CONNECT_TIME).longValue(); + } /** * Gets the success status stored in the sample. diff --git a/src/core/org/apache/jmeter/report/processor/graph/ConnectTimeValueSelector.java b/src/core/org/apache/jmeter/report/processor/graph/ConnectTimeValueSelector.java new file mode 100644 index 0000000000..8dfdcad139 --- /dev/null +++ b/src/core/org/apache/jmeter/report/processor/graph/ConnectTimeValueSelector.java @@ -0,0 +1,41 @@ +/* + * 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; + +import org.apache.jmeter.report.core.Sample; + +/** + * The class ConnectTimeValueSelector provides a projection from a sample to its + * connect time. + * + * @since 3.1 + */ +public class ConnectTimeValueSelector implements GraphValueSelector { + /* + * (non-Javadoc) + * + * @see + * org.apache.jmeter.report.csv.processor.GraphValueSelector#select(java + * .lang.String, java.lang.Object, org.apache.jmeter.report.csv.core.Sample) + */ + @Override + public double select(String series, Sample sample) { + return sample.getConnectTime(); + } + +} diff --git a/src/core/org/apache/jmeter/report/processor/graph/impl/ConnectTimeOverTimeGraphConsumer.java b/src/core/org/apache/jmeter/report/processor/graph/impl/ConnectTimeOverTimeGraphConsumer.java new file mode 100644 index 0000000000..981bea8887 --- /dev/null +++ b/src/core/org/apache/jmeter/report/processor/graph/impl/ConnectTimeOverTimeGraphConsumer.java @@ -0,0 +1,74 @@ +/* + * 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.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.jmeter.report.processor.MeanAggregatorFactory; +import org.apache.jmeter.report.processor.graph.AbstractGraphConsumer; +import org.apache.jmeter.report.processor.graph.AbstractOverTimeGraphConsumer; +import org.apache.jmeter.report.processor.graph.ConnectTimeValueSelector; +import org.apache.jmeter.report.processor.graph.GroupInfo; +import org.apache.jmeter.report.processor.graph.NameSeriesSelector; +import org.apache.jmeter.report.processor.graph.TimeStampKeysSelector; +import org.apache.jmeter.util.JMeterUtils; + +/** + * The class ConnectTimeOverTimeGraphConsumer provides a graph to visualize Connection time + * over time. + * + * @since 3.1 + */ +public class ConnectTimeOverTimeGraphConsumer extends AbstractOverTimeGraphConsumer { + private static final boolean CONNECT_TIME_SAVED = + JMeterUtils.getPropDefault("jmeter.save.saveservice.connect_time", false); //$NON-NLS-1$ + + /* + * (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 createGroupInfos() { + if(!CONNECT_TIME_SAVED) { + return Collections.emptyMap(); + } + HashMap groupInfos = new HashMap<>(); + groupInfos.put(AbstractGraphConsumer.DEFAULT_GROUP, new GroupInfo( + new MeanAggregatorFactory(), new NameSeriesSelector(), + new ConnectTimeValueSelector(), false, false)); + return groupInfos; + } +} diff --git a/xdocs/changes.xml b/xdocs/changes.xml index f3d2ff6ab3..a00b540ae2 100644 --- a/xdocs/changes.xml +++ b/xdocs/changes.xml @@ -137,6 +137,7 @@ Summary
  • 59956Web Report / Dashboard : Add ability to generate a graph for a range of data
  • 60065Report / Dashboard : Improve Dashboard Error Summary by adding response message to "Type of error". Contributed by Ubik Load Pack (support at ubikloadpack.com)
  • 60079Report / Dashboard : Add a new "Response Time Overview" graph
  • +
  • 60080Report / Dashboard : Add a new "Connect Time Over Time " graph. Contributed by Ubik Load Pack (support at ubikloadpack.com)
  • Non-functional changes diff --git a/xdocs/usermanual/generating-dashboard.xml b/xdocs/usermanual/generating-dashboard.xml index 57623d3d74..ad4641e43b 100644 --- a/xdocs/usermanual/generating-dashboard.xml +++ b/xdocs/usermanual/generating-dashboard.xml @@ -74,6 +74,7 @@ jmeter.save.saveservice.successful = true jmeter.save.saveservice.thread_counts = true jmeter.save.saveservice.thread_name = true jmeter.save.saveservice.time = true +jmeter.save.saveservice.connect_time = true # the timestamp format must include the time and should include the date. # For example the default, which is milliseconds since the epoch: jmeter.save.saveservice.timestamp_format = ms @@ -583,6 +584,11 @@ jmeter.reportgenerator.exporter.html.filters_only_sample_series=true This graph represents the average latency time over time. True + + ConnectTimeOverTimeGraphConsumer + This graph represents the connection time over time. + True + LatencyVSRequestGraphConsumer This graph represents the median and average latency time