/** * Copy constructor to create a duplicate of existing instance (without the * disadvantages of clone() * * @param src existing RunningSample to be copied */ public RunningSample(RunningSample src) { this.counter = src.counter; this.errorCount = src.errorCount; this.firstTime = src.firstTime; this.index = src.index; this.label = src.label; this.lastTime = src.lastTime; this.max = src.max; this.min = src.min; this.runningSum = src.runningSum; }
/** * Adds another RunningSample to this one. * Does not check if it has the same label and index. */ public void AddSample(RunningSample rs) { this.counter += rs.counter; this.errorCount += rs.errorCount; this.runningSum += rs.runningSum; if (this.firstTime > rs.firstTime) { this.firstTime = rs.firstTime; } if (this.lastTime < rs.lastTime) { this.lastTime = rs.lastTime; } if (this.max < rs.max) { this.max = rs.max; } if (this.min > rs.min) { this.min = rs.min; } }
/** * @param myTotal * @param string * @return */ private static String Format(String name, RunningSample s, String type) { StringBuilder tmp = new StringBuilder(20); // for intermediate use StringBuilder sb = new StringBuilder(100); // output line buffer sb.Append(name); sb.Append(" "); sb.Append(type); sb.Append(" "); sb.Append(s.getNumSamples()); sb.Append(" in "); long elapsed = s.getElapsed(); long elapsedSec = (elapsed + 500) / 1000; // rounded seconds if (elapsedSec > 100 // No point displaying decimals (less than 1% error) || (elapsed - elapsedSec * 1000) < 50 // decimal would be zero ) { sb.Append(elapsedSec); } else { double elapsedSecf = elapsed / 1000.0d; // fractional seconds sb.Append(elapsedSecf); // This will round } sb.Append("s = "); if (elapsed > 0) { sb.Append(s.getRate()); } else { sb.Append("******");// Rate is effectively infinite } sb.Append("/s Avg: "); sb.Append(s.getAverage()); sb.Append(" Min: "); sb.Append(s.getMin()); sb.Append(" Max: "); sb.Append(s.getMax()); sb.Append(" Err: "); sb.Append(s.getErrorCount()); sb.Append(" ("); sb.Append(s.getErrorPercentageString()); sb.Append(")"); if ("+".Equals(type)) { ThreadCounts tc = NetMeterContextManager.GetThreadCounts(); sb.Append(" Active: "); sb.Append(tc.activeThreads); sb.Append(" Started: "); sb.Append(tc.startedThreads); sb.Append(" Finished: "); sb.Append(tc.finishedThreads); } return sb.ToString(); }
/** * Accumulates the sample in two SampleResult objects - one for running * totals, and the other for deltas. * * @see org.apache.jmeter.samplers.SampleListener#sampleOccurred(org.apache.jmeter.samplers.SampleEvent) */ public void ExecutionOccurred(ExecutionEvent e) { ExecuteResult s = e.getResult(); Int64 now = DateTime.Now.Ticks;// in seconds RunningSample myDelta = null; RunningSample myTotal = null; Boolean reportNow = false; /* * Have we reached the reporting boundary? * Need to allow for a margin of error, otherwise can miss the slot. * Also need to check we've not hit the window already */ Monitor.Enter(myTotals); try { if (s != null) { myTotals.delta.AddSample(s); } if ((now > myTotals.last + INTERVAL_WINDOW) && (now % INTERVAL <= INTERVAL_WINDOW)) { reportNow = true; // copy the data to minimise the synch time myDelta = new RunningSample(myTotals.delta); myTotals.MoveDelta(); myTotal = new RunningSample(myTotals.total); myTotals.last = now; // stop double-reporting } } finally { Monitor.Exit(myTotals); } if (reportNow) { String str; str = Format(myName, myDelta, "+"); if (TOLOG) { log.Info(str); } if (TOCONSOLE) { System.Console.WriteLine(str); } // Only if we have updated them if (myTotal != null && myDelta != null &&myTotal.getNumSamples() != myDelta.getNumSamples()) { str = Format(myName, myTotal, "="); if (TOLOG) { log.Info(str); } if (TOCONSOLE) { System.Console.WriteLine(str); } } } }