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 2008/05/15 22:29:59 UTC
svn commit: r656818 - in /jakarta/jmeter/trunk:
src/core/org/apache/jmeter/reporters/Summariser.java xdocs/changes.xml
Author: sebb
Date: Thu May 15 13:29:59 2008
New Revision: 656818
URL: http://svn.apache.org/viewvc?rev=656818&view=rev
Log:
Summariser updated to handle variable names
Modified:
jakarta/jmeter/trunk/src/core/org/apache/jmeter/reporters/Summariser.java
jakarta/jmeter/trunk/xdocs/changes.xml
Modified: jakarta/jmeter/trunk/src/core/org/apache/jmeter/reporters/Summariser.java
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/src/core/org/apache/jmeter/reporters/Summariser.java?rev=656818&r1=656817&r2=656818&view=diff
==============================================================================
--- jakarta/jmeter/trunk/src/core/org/apache/jmeter/reporters/Summariser.java (original)
+++ jakarta/jmeter/trunk/src/core/org/apache/jmeter/reporters/Summariser.java Thu May 15 13:29:59 2008
@@ -21,14 +21,15 @@
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.Hashtable;
+import java.util.Map;
import org.apache.jmeter.engine.event.LoopIterationEvent;
-import org.apache.jmeter.samplers.Clearable;
import org.apache.jmeter.samplers.SampleEvent;
import org.apache.jmeter.samplers.SampleListener;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.AbstractTestElement;
import org.apache.jmeter.testelement.TestListener;
+import org.apache.jmeter.testelement.ThreadListener;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.visualizers.RunningSample;
import org.apache.jorphan.logging.LoggingManager;
@@ -52,7 +53,7 @@
* Also, the sum of the delta intervals will be larger than the overall elapsed time.
*
*/
-public class Summariser extends AbstractTestElement implements Serializable, SampleListener, TestListener, Clearable {
+public class Summariser extends AbstractTestElement implements Serializable, SampleListener, TestListener, ThreadListener {
private static final Logger log = LoggingManager.getLoggerForClass();
/** interval between summaries (in seconds) default 3 minutes */
@@ -64,14 +65,32 @@
/** Write messages to System.out ? */
private static final boolean TOOUT = JMeterUtils.getPropDefault("summariser.out", true); //$NON-NLS-1$
+ /*
+ * Ensure that a report is not skipped if we are slightly late in checking
+ * the time.
+ */
+ private static final int INTERVAL_WINDOW = 5; // in seconds
+
/**
* Summariser elements are cloned for each thread in each group; this Map is
* used to allow them to share the same statistics. The key is the
* Summariser name, so all Summarisers with the same name will use the same
* accumulators.
*/
+ //@GuardedBy("accumulators")
private static final Hashtable accumulators = new Hashtable();
+ /*
+ * Cached copy of Totals for this instance.
+ * The variables do not need to be synchronised,
+ * as they are not shared between threads
+ * However the contents do need to be synchronized.
+ */
+ //@GuardedBy("myTotals")
+ private transient Totals myTotals = null;
+
+ private transient String myName;
+
/*
* Constructor is initially called once for each occurrence in the test plan.
* For GUI, several more instances are created.
@@ -81,9 +100,6 @@
*/
public Summariser() {
super();
- // log.debug(Thread.currentThread().getName());
- // System.out.println(">> "+me+" "+this.getName()+"
- // "+Thread.currentThread().getName());
}
/**
@@ -96,10 +112,6 @@
setName(name);
}
- public void clearData(){
- // not used
- }
-
/*
* Contains the items needed to collect stats for a summariser
*
@@ -107,43 +119,21 @@
private static class Totals {
/** Time of last summary (to prevent double reporting) */
- private long last = 0;// set to -1 by TestEnded to prevent double
- // reporting
+ private long last = 0;
- private RunningSample delta = new RunningSample("DELTA",0);
+ private final RunningSample delta = new RunningSample("DELTA",0);
- private RunningSample total = new RunningSample("TOTAL",0);
-
- private void clear() {
- delta.clear();
- total.clear();
- last = 0;
- }
+ private final RunningSample total = new RunningSample("TOTAL",0);
/**
* Add the delta values to the total values and clear the delta
*/
- private synchronized void moveDelta() {
+ private void moveDelta() {
total.addSample(delta);
delta.clear();
}
}
- /*
- * Cached copy of Totals for this instance.
- * The variables do not need to be synchronised,
- * as they are not shared between threads
- */
- private transient Totals myTotals = null;
-
- private transient String myName;
-
- /*
- * Ensure that a report is not skipped if we are slightly late in checking
- * the time.
- */
- private static final int INTERVAL_WINDOW = 5; // in seconds
-
/**
* Accumulates the sample in two SampleResult objects - one for running
* totals, and the other for deltas.
@@ -153,24 +143,6 @@
public void sampleOccurred(SampleEvent e) {
SampleResult s = e.getResult();
- // System.out.println("SO "+me+this.getName()+"
- // "+Thread.currentThread().getName()
- // +" "+s.getSampleLabel());
-
- if (myName == null) {
- myName = getName();
- }
-
- if (myTotals == null) {
- synchronized (accumulators) {
- myTotals = (Totals) accumulators.get(myName);
- }
- }
-
- if (s != null) {
- myTotals.delta.addSample(s);
- }
-
long now = System.currentTimeMillis() / 1000;// in seconds
RunningSample myDelta = null;
@@ -183,6 +155,10 @@
* Also need to check we've not hit the window already
*/
synchronized (myTotals) {
+ if (s != null) {
+ myTotals.delta.addSample(s);
+ }
+
if ((now > myTotals.last + INTERVAL_WINDOW) && (now % INTERVAL <= INTERVAL_WINDOW)) {
reportNow = true;
@@ -191,12 +167,12 @@
myTotals.moveDelta();
myTotal = new RunningSample(myTotals.total);
- myTotals.last = now;
+ myTotals.last = now; // stop double-reporting
}
}
if (reportNow) {
String str;
- str = format(myDelta, "+");
+ str = format(myName, myDelta, "+");
if (TOLOG) {
log.info(str);
}
@@ -206,7 +182,7 @@
// Only if we have updated them
if (myTotal != null && myDelta != null &&myTotal.getNumSamples() != myDelta.getNumSamples()) {
- str = format(myTotal, "=");
+ str = format(myName, myTotal, "=");
if (TOLOG) {
log.info(str);
}
@@ -238,10 +214,10 @@
* @param string
* @return
*/
- private String format(RunningSample s, String type) {
+ private String format(String name, RunningSample s, String type) {
StringBuffer tmp = new StringBuffer(20); // for intermediate use
StringBuffer sb = new StringBuffer(100); // output line buffer
- sb.append(myName);
+ sb.append(name);
sb.append(" ");
sb.append(type);
sb.append(" ");
@@ -303,64 +279,59 @@
*/
public void testEnded() {
testEnded("local");
-
}
/*
* (non-Javadoc)
*
+ * Called once for each Summariser in the test plan.
+ * There may be more than one summariser with the same name,
+ * however they will all be called before the test proper starts,
+ * so it does not matter if the totals are reset again.
+ *
* @see org.apache.jmeter.testelement.TestListener#testStarted(java.lang.String)
*/
public void testStarted(String host) {
- myName = this.getName();
-
- // Hashtable is synchronised, but there could be more than one Summariser
- // with the same name, so we need to synchronise.
+ // testStarted and testFinished are called from different threads,
+ // so need to synch for visibility.
synchronized (accumulators) {
- Totals tots = (Totals) accumulators.get(myName);
- if (tots != null) {// This can be null (before first sample)
- tots.clear();
- } else {
- // System.out.println("Creating totals for "+myName);
- tots = new Totals();
- accumulators.put(myName, tots);
- }
+ accumulators.clear(); // Should not be needed, but just in case previous run does not clear up.
}
}
/*
- * (non-Javadoc) Can be called more than once with the same name, so need to
- * synch. However, there is no need to create copies, to shorten the synch
- * zone, as timing is not critical at the end of the test.
- *
+ * (non-Javadoc)
+ * Called from a different thread as testStarted() but using the same instance.
+ * So synch is needed to fetch the accumulator, and the myName field will already be set up.
* @see org.apache.jmeter.testelement.TestListener#testEnded(java.lang.String)
*/
public void testEnded(String host) {
- // System.out.println("TE "+me+this.getName()+"
- // "+Thread.currentThread().getName());
+ Object[] totals;
synchronized (accumulators) {
- Totals t = (Totals) accumulators.get(myName);
- if (t.last != -1) {
- String str;
- if (t.total.getNumSamples() != 0) {// Only print delta if different
- // from total
- str = format(t.delta, "+");
- if (TOLOG) {
- log.info(str);
- }
- if (TOOUT) {
- System.out.println(str);
- }
- }
- t.moveDelta();
- str = format(t.total, "=");
+ totals = accumulators.entrySet().toArray();
+ accumulators.clear(); // Instance is not needed anymore
+ }
+ for (int i=0; i<totals.length; i++) {
+ Map.Entry me = (Map.Entry)totals[i];
+ String str;
+ String name = (String) me.getKey();
+ Totals total = (Totals) me.getValue();
+ if (total.total.getNumSamples() != 0) {// Only print delta if different from total
+ str = format(name, total.delta, "+");
if (TOLOG) {
log.info(str);
}
if (TOOUT) {
System.out.println(str);
}
- t.last = -1;
+ }
+ total.moveDelta();
+ str = format(name, total.total, "=");
+ if (TOLOG) {
+ log.info(str);
+ }
+ if (TOOUT) {
+ System.out.println(str);
}
}
}
@@ -374,4 +345,19 @@
// not used
}
+ public void threadFinished() {
+ // not used
+ }
+
+ public void threadStarted() {
+ myName = getName();
+ synchronized (accumulators) {
+ myTotals = (Totals) accumulators.get(myName);
+ if (myTotals == null){
+ myTotals = new Totals();
+ accumulators.put(myName, myTotals);
+ }
+ }
+ }
+
}
\ No newline at end of file
Modified: jakarta/jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jakarta/jmeter/trunk/xdocs/changes.xml?rev=656818&r1=656817&r2=656818&view=diff
==============================================================================
--- jakarta/jmeter/trunk/xdocs/changes.xml (original)
+++ jakarta/jmeter/trunk/xdocs/changes.xml Thu May 15 13:29:59 2008
@@ -220,6 +220,7 @@
<li>Give Beanshell test elements access to JMeter Properties via "props" object</li>
<li>Added BSF PreProcessor, PostProcessor and Assertion test elements</li>
<li>All BSF elements now have access to System.out via the variable "OUT"</li>
+<li>Summariser updated to handle variable names</li>
</ul>
<h4>Non-functional changes</h4>
---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org