You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by se...@apache.org on 2006/05/15 00:41:30 UTC
svn commit: r406460 - in /jakarta/jmeter/branches/rel-2-1:
src/components/org/apache/jmeter/visualizers/
src/core/org/apache/jmeter/resources/ src/jorphan/org/apache/jorphan/math/
xdocs/ xdocs/images/screenshots/ xdocs/usermanual/
Author: sebb
Date: Sun May 14 15:41:29 2006
New Revision: 406460
URL: http://svn.apache.org/viewcvs?rev=406460&view=rev
Log:
Create Summary Report visualiser
Added:
jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java (with props)
jakarta/jmeter/branches/rel-2-1/xdocs/images/screenshots/summary_report.png (with props)
Modified:
jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties
jakarta/jmeter/branches/rel-2-1/src/jorphan/org/apache/jorphan/math/Calculator.java
jakarta/jmeter/branches/rel-2-1/xdocs/changes.xml
jakarta/jmeter/branches/rel-2-1/xdocs/images/screenshots/aggregate_report.png
jakarta/jmeter/branches/rel-2-1/xdocs/usermanual/component_reference.xml
Added: jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java
URL: http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java?rev=406460&view=auto
==============================================================================
--- jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java (added)
+++ jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java Sun May 14 15:41:29 2006
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2002-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.visualizers;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.BoxLayout;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.jmeter.samplers.Clearable;
+import org.apache.jmeter.samplers.SampleResult;
+import org.apache.jmeter.testelement.TestElement;
+import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jmeter.visualizers.gui.AbstractVisualizer;
+import org.apache.jorphan.gui.ObjectTableModel;
+import org.apache.jorphan.math.Calculator;
+import org.apache.jorphan.reflect.Functor;
+
+/**
+ * Simpler (lower memory) version of Aggregate Report (StatVisualizer).
+ * Excludes the Median and 90% columns, which are expensive in memory terms
+ */
+public class SummaryReport extends AbstractVisualizer implements Clearable {
+ private final String[] COLUMNS = {
+ JMeterUtils.getResString("sampler_label"), //$NON-NLS-1$
+ JMeterUtils.getResString("aggregate_report_count"), //$NON-NLS-1$
+ JMeterUtils.getResString("average"), //$NON-NLS-1$
+ JMeterUtils.getResString("aggregate_report_min"), //$NON-NLS-1$
+ JMeterUtils.getResString("aggregate_report_max"), //$NON-NLS-1$
+ JMeterUtils.getResString("aggregate_report_error%"), //$NON-NLS-1$
+ JMeterUtils.getResString("aggregate_report_rate"), //$NON-NLS-1$
+ JMeterUtils.getResString("aggregate_report_bandwidth"), //$NON-NLS-1$
+ JMeterUtils.getResString("average_bytes"), //$NON-NLS-1$
+ };
+
+ private final String TOTAL_ROW_LABEL
+ = JMeterUtils.getResString("aggregate_report_total_label"); //$NON-NLS-1$
+
+ protected JTable myJTable;
+
+ protected JScrollPane myScrollPane;
+
+ transient private ObjectTableModel model;
+
+ Map tableRows = Collections.synchronizedMap(new HashMap());
+
+ public SummaryReport() {
+ super();
+ model = new ObjectTableModel(COLUMNS,
+ new Functor[] {
+ new Functor("getLabel"), //$NON-NLS-1$
+ new Functor("getCount"), //$NON-NLS-1$
+ new Functor("getMeanAsNumber"), //$NON-NLS-1$
+ new Functor("getMin"), //$NON-NLS-1$
+ new Functor("getMax"), //$NON-NLS-1$
+ new Functor("getErrorPercentageString"), //$NON-NLS-1$
+ new Functor("getRateString"), //$NON-NLS-1$
+ new Functor("getKBPerSecondString"), //$NON-NLS-1$
+ new Functor("getPageSizeString"), //$NON-NLS-1$
+ },
+ new Functor[] { null, null, null, null, null, null, null, null , null },
+ new Class[] { String.class, Long.class, Long.class, Long.class,
+ Long.class, String.class, String.class, String.class, String.class });
+ clear();
+ init();
+ }
+
+ public String getLabelResource() {
+ return "summary_report"; //$NON-NLS-1$
+ }
+
+ public void add(SampleResult res) {
+ Calculator row = null;
+ synchronized (tableRows) {
+ row = (Calculator) tableRows.get(res.getSampleLabel());
+ if (row == null) {
+ row = new Calculator(res.getSampleLabel());
+ tableRows.put(row.getLabel(), row);
+ model.insertRow(row, model.getRowCount() - 1);
+ }
+ }
+ row.addSample(res);
+ ((Calculator) tableRows.get(TOTAL_ROW_LABEL)).addSample(res);
+ model.fireTableDataChanged();
+ }
+
+ /**
+ * Clears this visualizer and its model, and forces a repaint of the table.
+ */
+ public void clear() {
+ model.clearData();
+ tableRows.clear();
+ tableRows.put(TOTAL_ROW_LABEL, new Calculator(TOTAL_ROW_LABEL));
+ model.addRow(tableRows.get(TOTAL_ROW_LABEL));
+ }
+
+ // overrides AbstractVisualizer
+ // forces GUI update after sample file has been read
+ public TestElement createTestElement() {
+ TestElement t = super.createTestElement();
+
+ // sleepTill = 0;
+ return t;
+ }
+
+ /**
+ * Main visualizer setup.
+ */
+ private void init() {
+ this.setLayout(new BorderLayout());
+
+ // MAIN PANEL
+ JPanel mainPanel = new JPanel();
+ Border margin = new EmptyBorder(10, 10, 5, 10);
+
+ mainPanel.setBorder(margin);
+ mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
+
+ mainPanel.add(makeTitlePanel());
+
+ myJTable = new JTable(model);
+ myJTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
+ myScrollPane = new JScrollPane(myJTable);
+ this.add(mainPanel, BorderLayout.NORTH);
+ this.add(myScrollPane, BorderLayout.CENTER);
+ }
+}
Propchange: jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision
Propchange: jakarta/jmeter/branches/rel-2-1/src/components/org/apache/jmeter/visualizers/SummaryReport.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties?rev=406460&r1=406459&r2=406460&view=diff
==============================================================================
--- jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jakarta/jmeter/branches/rel-2-1/src/core/org/apache/jmeter/resources/messages.properties Sun May 14 15:41:29 2006
@@ -61,6 +61,7 @@
auth_manager_title=HTTP Authorization Manager
auths_stored=Authorizations Stored in the Authorization Manager
average=Average
+average_bytes=Avg. Bytes
bind=Thread Bind
browse=Browse...
bsf_sampler_title=BSF Sampler
Modified: jakarta/jmeter/branches/rel-2-1/src/jorphan/org/apache/jorphan/math/Calculator.java
URL: http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/src/jorphan/org/apache/jorphan/math/Calculator.java?rev=406460&r1=406459&r2=406460&view=diff
==============================================================================
--- jakarta/jmeter/branches/rel-2-1/src/jorphan/org/apache/jorphan/math/Calculator.java (original)
+++ jakarta/jmeter/branches/rel-2-1/src/jorphan/org/apache/jorphan/math/Calculator.java Sun May 14 15:41:29 2006
@@ -17,6 +17,10 @@
package org.apache.jorphan.math;
+import java.text.DecimalFormat;
+
+import org.apache.jmeter.samplers.SampleResult;
+
/**
* Class to calculate various items that don't require all previous results to be saved:
* - mean = average
@@ -26,6 +30,12 @@
*/
public class Calculator {
+ private static DecimalFormat rateFormatter = new DecimalFormat("#.0");
+
+ private static DecimalFormat errorFormatter = new DecimalFormat("#0.00%");
+
+ private static DecimalFormat kbFormatter = new DecimalFormat("#0.00");
+
private double sum = 0;
private double sumOfSquares = 0;
@@ -41,8 +51,20 @@
private long maximum = Long.MIN_VALUE;
private long minimum = Long.MAX_VALUE;
+
+ private int errors = 0;
- public void clear() {
+ private final String label;
+
+ public Calculator() {
+ this.label = "";
+ }
+
+ public Calculator(String label) {
+ this.label = label;
+ }
+
+ public void clear() {
maximum = Long.MIN_VALUE;
minimum = Long.MAX_VALUE;
sum = 0;
@@ -78,6 +100,10 @@
return mean;
}
+ public Number getMeanAsNumber() {
+ return new Long((long) mean);
+ }
+
public double getStandardDeviation() {
return deviation;
}
@@ -93,4 +119,148 @@
public int getCount() {
return count;
}
+
+ public String getLabel() {
+ return label;
+ }
+
+ private long startTime = 0;
+ private long elapsedTime = 0;
+
+ public void addSample(SampleResult res) {
+ addBytes(res.getBytes());
+ addValue(res.getTime());
+ if (!res.isSuccessful()) errors++;
+ if (startTime == 0){
+ startTime=res.getStartTime();
+ }
+ elapsedTime=res.getEndTime()-startTime;
+ }
+
+ /**
+ * Returns the raw double value of the percentage of samples with errors
+ * that were recorded. (Between 0.0 and 1.0) If you want a nicer return
+ * format, see {@link #getErrorPercentageString()}.
+ *
+ * @return the raw double value of the percentage of samples with errors
+ * that were recorded.
+ */
+ public double getErrorPercentage() {
+ double rval = 0.0;
+
+ if (count == 0) {
+ return (rval);
+ }
+ rval = (double) errors / (double) count;
+ return (rval);
+ }
+
+ /**
+ * Returns a String which represents the percentage of sample errors that
+ * have occurred. ("0.00%" through "100.00%")
+ *
+ * @return a String which represents the percentage of sample errors that
+ * have occurred.
+ */
+ public String getErrorPercentageString() {
+ double myErrorPercentage = this.getErrorPercentage();
+ if (myErrorPercentage < 0) {
+ myErrorPercentage = 0.0;
+ }
+
+ return (errorFormatter.format(myErrorPercentage));
+ }
+
+ /**
+ * Returns the throughput associated to this sampler in requests per second.
+ * May be slightly skewed because it takes the timestamps of the first and
+ * last samples as the total time passed, and the test may actually have
+ * started before that start time and ended after that end time.
+ */
+ public double getRate() {
+ if (elapsedTime == 0)
+ return 0.0;
+
+ return ((double) count / (double) elapsedTime ) * 1000;
+ }
+
+ /**
+ * Returns a String that represents the throughput associated for this
+ * sampler, in units appropriate to its dimension:
+ * <p>
+ * The number is represented in requests/second or requests/minute or
+ * requests/hour.
+ * <p>
+ * Examples: "34.2/sec" "0.1/sec" "43.0/hour" "15.9/min"
+ *
+ * @return a String representation of the rate the samples are being taken
+ * at.
+ */
+ public String getRateString() {
+ double rate = getRate();
+
+ if (rate == Double.MAX_VALUE) {
+ return "N/A";
+ }
+
+ String unit = "sec";
+
+ if (rate < 1.0) {
+ rate *= 60.0;
+ unit = "min";
+ }
+ if (rate < 1.0) {
+ rate *= 60.0;
+ unit = "hour";
+ }
+
+ String rval = rateFormatter.format(rate) + "/" + unit;
+
+ return (rval);
+ }
+
+ /**
+ * calculates the average page size, which means divide the bytes by number
+ * of samples.
+ *
+ * @return
+ */
+ public double getPageSize() {
+ if (count > 0 && bytes > 0) {
+ return bytes / count;
+ }
+ return 0.0;
+ }
+
+ /**
+ * formats the rate
+ *
+ * @return
+ */
+ public String getPageSizeString() {
+ double rate = getPageSize() / 1024;
+ return kbFormatter.format(rate);
+ }
+
+ /**
+ * Throughput in bytes / second
+ *
+ * @return
+ */
+ public double getBytesPerSecond() {
+ if (elapsedTime > 0) {
+ return bytes / ((double) elapsedTime / 1000);
+ }
+ return 0.0;
+ }
+
+ /**
+ * formats the Page Size
+ *
+ * @return
+ */
+ public String getKBPerSecondString() {
+ double rate = getBytesPerSecond() / 1024;
+ return kbFormatter.format(rate);
+ }
}
Modified: jakarta/jmeter/branches/rel-2-1/xdocs/changes.xml
URL: http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/xdocs/changes.xml?rev=406460&r1=406459&r2=406460&view=diff
==============================================================================
--- jakarta/jmeter/branches/rel-2-1/xdocs/changes.xml (original)
+++ jakarta/jmeter/branches/rel-2-1/xdocs/changes.xml Sun May 14 15:41:29 2006
@@ -99,6 +99,7 @@
<li>Add Thread Name to Tree and Table Views</li>
<li>Add debug functions: What class, debug on, debug off</li>
<li>Non-caching Calculator - used by Table Visualiser to reduce memory footprint</li>
+<li>Summary Report - similar to Aggregate Report, but uses less memory</li>
</ul>
<h4>Bug fixes:</h4>
Modified: jakarta/jmeter/branches/rel-2-1/xdocs/images/screenshots/aggregate_report.png
URL: http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/xdocs/images/screenshots/aggregate_report.png?rev=406460&r1=406459&r2=406460&view=diff
==============================================================================
Binary files - no diff available.
Added: jakarta/jmeter/branches/rel-2-1/xdocs/images/screenshots/summary_report.png
URL: http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/xdocs/images/screenshots/summary_report.png?rev=406460&view=auto
==============================================================================
Binary file - no diff available.
Propchange: jakarta/jmeter/branches/rel-2-1/xdocs/images/screenshots/summary_report.png
------------------------------------------------------------------------------
svn:mime-type = image/png
Modified: jakarta/jmeter/branches/rel-2-1/xdocs/usermanual/component_reference.xml
URL: http://svn.apache.org/viewcvs/jakarta/jmeter/branches/rel-2-1/xdocs/usermanual/component_reference.xml?rev=406460&r1=406459&r2=406460&view=diff
==============================================================================
--- jakarta/jmeter/branches/rel-2-1/xdocs/usermanual/component_reference.xml (original)
+++ jakarta/jmeter/branches/rel-2-1/xdocs/usermanual/component_reference.xml Sun May 14 15:41:29 2006
@@ -1587,16 +1587,22 @@
It is important to choose the sampler names correctly to get the best results from
the Aggregate Report.
</p>
-<p>URL - The URL of the sample.</p>
-<p># Samples - The number of samples for the URL</p>
-<p>Average - The average time of a set of results</p>
-<p>Median - The median is the time in the middle of a set of results.</p>
-<p>90% Line - 90% of the results finished faster than the line.</p>
-<p>Min - The lowest time for the samples of the given URL</p>
-<p>Max - The longest time for the samples of the given URL</p>
-<p>Error % - Percent of requests with errors</p>
-<p>Throughput - Throughput measured in requests per second/minute/hour</p>
-<p>Kb/sec - The throughput measured in Kilobytes per second</p>
+<note>
+Calculation of the Median and 90% Line values requires a lot of memory as details of every Sample have to be saved.
+See the <complink name="Summary Report"/> for a similar Listener that does not need so much memory.
+</note>
+<ul>
+<li>Label - The label of the sample.</li>
+<li># Samples - The number of samples for the URL</li>
+<li>Average - The average time of a set of results</li>
+<li>Median - The median is the time in the middle of a set of results.</li>
+<li>90% Line - 90% of the results finished faster than the line.</li>
+<li>Min - The lowest time for the samples of the given URL</li>
+<li>Max - The longest time for the samples of the given URL</li>
+<li>Error % - Percent of requests with errors</li>
+<li>Throughput - Throughput measured in requests per second/minute/hour</li>
+<li>Kb/sec - The throughput measured in Kilobytes per second</li>
+</ul>
</description>
</component>
@@ -1703,6 +1709,33 @@
</ul>
<p>For details of all the methods available on each of the above variables, please check the Javadoc</p>
<p>If the property <b>beanshell.listener.init</b> is defined, this is used to load an initialisation file, which can be used to define methods etc for use in the BeanShell script.</p>
+</component>
+
+<component name="Summary Report" index="§-num;.3.15" screenshot="summary_report.png">
+<description>The summary report creates a table row for each differently named request in your
+test. This is similar to the <complink name="Aggregate Report"/> , except that it uses less memory.
+<p>
+The thoughput is calculated from the point of view of the sampler target
+(e.g. the remote server in the case of HTTP samples).
+JMeter takes into account the total time over which the requests have been generated.
+If other samplers and timers are in the same thread, these will increase the total time,
+and therefore reduce the throughput value.
+So two identical samplers with different names will have half the throughput of two samplers with the same name.
+It is important to choose the sampler labels correctly to get the best results from
+the Report.
+</p>
+<ul>
+<li>Label - The label of the sample.</li>
+<li># Samples - The number of samples for the URL</li>
+<li>Average - The average time of a set of results</li>
+<li>Min - The lowest time for the samples of the given URL</li>
+<li>Max - The longest time for the samples of the given URL</li>
+<li>Error % - Percent of requests with errors</li>
+<li>Throughput - Throughput measured in requests per second/minute/hour</li>
+<li>Kb/sec - The throughput measured in Kilobytes per second</li>
+<li>Avg. Bytes - average size of the sample response in bytes.</li>
+</ul>
+</description>
</component>
---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org