* Issue #2288 - Cleanup the statistics classes. Cleaned up code, added Javadocs. Renamed SampleStatistics.set(long) to record(long). Signed-off-by: Simone Bordet <simone.bordet@gmail.com> * toString stddev Signed-off-by: Greg Wilkins <gregw@webtide.com>
This commit is contained in:
parent
5712b0217f
commit
a3100e0211
|
@ -94,7 +94,7 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio
|
||||||
_connections.decrement();
|
_connections.decrement();
|
||||||
|
|
||||||
long elapsed = System.currentTimeMillis() - connection.getCreatedTimeStamp();
|
long elapsed = System.currentTimeMillis() - connection.getCreatedTimeStamp();
|
||||||
_connectionsDuration.set(elapsed);
|
_connectionsDuration.record(elapsed);
|
||||||
|
|
||||||
long bytesIn = connection.getBytesIn();
|
long bytesIn = connection.getBytesIn();
|
||||||
if (bytesIn > 0)
|
if (bytesIn > 0)
|
||||||
|
|
|
@ -80,10 +80,10 @@ public class ConnectorStatistics extends AbstractLifeCycle implements Dumpable,
|
||||||
{
|
{
|
||||||
long msgsIn=connection.getMessagesIn();
|
long msgsIn=connection.getMessagesIn();
|
||||||
long msgsOut=connection.getMessagesOut();
|
long msgsOut=connection.getMessagesOut();
|
||||||
_messagesIn.set(msgsIn);
|
_messagesIn.record(msgsIn);
|
||||||
_messagesOut.set(msgsOut);
|
_messagesOut.record(msgsOut);
|
||||||
_connectionStats.decrement();
|
_connectionStats.decrement();
|
||||||
_connectionDurationStats.set(System.currentTimeMillis()-connection.getCreatedTimeStamp());
|
_connectionDurationStats.record(System.currentTimeMillis()-connection.getCreatedTimeStamp());
|
||||||
|
|
||||||
Sample sample=_samples.remove(connection);
|
Sample sample=_samples.remove(connection);
|
||||||
if (sample!=null)
|
if (sample!=null)
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
|
||||||
final long elapsed = System.currentTimeMillis()-request.getTimeStamp();
|
final long elapsed = System.currentTimeMillis()-request.getTimeStamp();
|
||||||
|
|
||||||
long d=_requestStats.decrement();
|
long d=_requestStats.decrement();
|
||||||
_requestTimeStats.set(elapsed);
|
_requestTimeStats.record(elapsed);
|
||||||
|
|
||||||
updateResponse(request);
|
updateResponse(request);
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
|
||||||
final long dispatched=now-start;
|
final long dispatched=now-start;
|
||||||
|
|
||||||
_dispatchedStats.decrement();
|
_dispatchedStats.decrement();
|
||||||
_dispatchedTimeStats.set(dispatched);
|
_dispatchedTimeStats.record(dispatched);
|
||||||
|
|
||||||
if (state.isSuspended())
|
if (state.isSuspended())
|
||||||
{
|
{
|
||||||
|
@ -197,7 +197,7 @@ public class StatisticsHandler extends HandlerWrapper implements Graceful
|
||||||
else if (state.isInitial())
|
else if (state.isInitial())
|
||||||
{
|
{
|
||||||
long d=_requestStats.decrement();
|
long d=_requestStats.decrement();
|
||||||
_requestTimeStats.set(dispatched);
|
_requestTimeStats.record(dispatched);
|
||||||
updateResponse(baseRequest);
|
updateResponse(baseRequest);
|
||||||
|
|
||||||
// If we have no more dispatches, should we signal shutdown?
|
// If we have no more dispatches, should we signal shutdown?
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.server.session;
|
package org.eclipse.jetty.server.session;
|
||||||
|
|
||||||
import static java.lang.Math.round;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -63,9 +61,11 @@ import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
||||||
import org.eclipse.jetty.util.statistic.SampleStatistic;
|
import org.eclipse.jetty.util.statistic.SampleStatistic;
|
||||||
|
import org.eclipse.jetty.util.thread.Locker.Lock;
|
||||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
||||||
import org.eclipse.jetty.util.thread.Scheduler;
|
import org.eclipse.jetty.util.thread.Scheduler;
|
||||||
import org.eclipse.jetty.util.thread.Locker.Lock;
|
|
||||||
|
import static java.lang.Math.round;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
|
@ -1235,7 +1235,7 @@ public class SessionHandler extends ScopedHandler
|
||||||
|
|
||||||
if (session != null)
|
if (session != null)
|
||||||
{
|
{
|
||||||
_sessionTimeStats.set(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0));
|
_sessionTimeStats.record(round((System.currentTimeMillis() - session.getSessionData().getCreated())/1000.0));
|
||||||
session.finishInvalidate();
|
session.finishInvalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,51 +22,53 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.LongAccumulator;
|
import java.util.concurrent.atomic.LongAccumulator;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/**
|
||||||
/** Statistics on a counter value.
|
* <p>Statistics on a counter value.</p>
|
||||||
* <p>
|
* <p>This class keeps the total, current and maximum value of a counter
|
||||||
* Keep total, current and maximum values of a counter that
|
* that can be incremented and decremented. The total refers only to increments.</p>
|
||||||
* can be incremented and decremented. The total refers only
|
|
||||||
* to increments.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CounterStatistic
|
public class CounterStatistic
|
||||||
{
|
{
|
||||||
protected final LongAccumulator _max = new LongAccumulator(Math::max,0L);
|
private final LongAccumulator _max = new LongAccumulator(Math::max, 0L);
|
||||||
protected final AtomicLong _current = new AtomicLong();
|
private final AtomicLong _current = new AtomicLong();
|
||||||
protected final LongAdder _total = new LongAdder();
|
private final LongAdder _total = new LongAdder();
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/**
|
||||||
|
* Resets the max and total to the current value.
|
||||||
|
*/
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
_total.reset();
|
_total.reset();
|
||||||
_max.reset();
|
_max.reset();
|
||||||
long current=_current.get();
|
long current = _current.get();
|
||||||
_total.add(current);
|
_total.add(current);
|
||||||
_max.accumulate(current);
|
_max.accumulate(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/**
|
||||||
|
* Resets the max, total and current value to the given parameter.
|
||||||
|
*
|
||||||
|
* @param value the new current value
|
||||||
|
*/
|
||||||
public void reset(final long value)
|
public void reset(final long value)
|
||||||
{
|
{
|
||||||
_current.set(value);
|
_current.set(value);
|
||||||
_total.reset();
|
_total.reset();
|
||||||
_max.reset();
|
_max.reset();
|
||||||
if (value>0)
|
if (value > 0)
|
||||||
{
|
{
|
||||||
_total.add(value);
|
_total.add(value);
|
||||||
_max.accumulate(value);
|
_max.accumulate(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @param delta the amount to add to the count
|
* @param delta the amount to add to the counter
|
||||||
* @return the new value
|
* @return the new counter value
|
||||||
*/
|
*/
|
||||||
public long add(final long delta)
|
public long add(final long delta)
|
||||||
{
|
{
|
||||||
long value=_current.addAndGet(delta);
|
long value = _current.addAndGet(delta);
|
||||||
if (delta > 0)
|
if (delta > 0)
|
||||||
{
|
{
|
||||||
_total.add(delta);
|
_total.add(delta);
|
||||||
|
@ -75,60 +77,56 @@ public class CounterStatistic
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* increment the value by one
|
* Increments the value by one.
|
||||||
* @return the new value, post increment
|
*
|
||||||
|
* @return the new counter value after the increment
|
||||||
*/
|
*/
|
||||||
public long increment()
|
public long increment()
|
||||||
{
|
{
|
||||||
long value=_current.incrementAndGet();
|
long value = _current.incrementAndGet();
|
||||||
_total.increment();
|
_total.increment();
|
||||||
_max.accumulate(value);
|
_max.accumulate(value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* decrement by 1
|
* Decrements the value by one.
|
||||||
* @return the new value, post-decrement
|
*
|
||||||
|
* @return the new counter value after the decrement
|
||||||
*/
|
*/
|
||||||
public long decrement()
|
public long decrement()
|
||||||
{
|
{
|
||||||
return _current.decrementAndGet();
|
return _current.decrementAndGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @return max value
|
* @return max counter value
|
||||||
*/
|
*/
|
||||||
public long getMax()
|
public long getMax()
|
||||||
{
|
{
|
||||||
return _max.get();
|
return _max.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @return current value
|
* @return current counter value
|
||||||
*/
|
*/
|
||||||
public long getCurrent()
|
public long getCurrent()
|
||||||
{
|
{
|
||||||
return _current.get();
|
return _current.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
/**
|
/**
|
||||||
* @return total value
|
* @return total counter value
|
||||||
*/
|
*/
|
||||||
public long getTotal()
|
public long getTotal()
|
||||||
{
|
{
|
||||||
return _total.sum();
|
return _total.sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s@%x{c=%d,m=%d,t=%d}",this.getClass().getSimpleName(),hashCode(),_current.get(),_max.get(),_total.sum());
|
return String.format("%s@%x{c=%d,m=%d,t=%d}", getClass().getSimpleName(), hashCode(), getCurrent(), getMax(), getTotal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,31 +22,26 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.LongAccumulator;
|
import java.util.concurrent.atomic.LongAccumulator;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.Atomics;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SampledStatistics
|
* <p>Statistics on a sampled value.</p>
|
||||||
* <p>
|
* <p>Provides max, total, mean, count, variance, and standard deviation of continuous sequence of samples.</p>
|
||||||
* Provides max, total, mean, count, variance, and standard deviation of continuous sequence of samples.
|
* <p>Calculates estimates of mean, variance, and standard deviation characteristics of a sample using a non synchronized
|
||||||
* <p>
|
|
||||||
* Calculates estimates of mean, variance, and standard deviation characteristics of a sample using a non synchronized
|
|
||||||
* approximation of the on-line algorithm presented in <cite>Donald Knuth's Art of Computer Programming, Volume 2,
|
* approximation of the on-line algorithm presented in <cite>Donald Knuth's Art of Computer Programming, Volume 2,
|
||||||
* Semi numerical Algorithms, 3rd edition, page 232, Boston: Addison-Wesley</cite>. that cites a 1962 paper by B.P. Welford that
|
* Semi numerical Algorithms, 3rd edition, page 232, Boston: Addison-Wesley</cite>. That cites a 1962 paper by B.P. Welford:
|
||||||
* can be found by following <a href="http://www.jstor.org/pss/1266577">Note on a Method for Calculating Corrected Sums
|
* <a href="http://www.jstor.org/pss/1266577">Note on a Method for Calculating Corrected Sums of Squares and Products</a></p>
|
||||||
* of Squares and Products</a>
|
* <p>This algorithm is also described in Wikipedia in the section "Online algorithm":
|
||||||
* <p>
|
* <a href="https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance">Algorithms for calculating variance</a>.</p>
|
||||||
* This algorithm is also described in Wikipedia at <a href=
|
|
||||||
* "http://en.wikipedia.org/w/index.php?title=Algorithms_for_calculating_variance&section=4#On-line_algorithm">
|
|
||||||
* Algorithms for calculating variance </a>
|
|
||||||
*/
|
*/
|
||||||
public class SampleStatistic
|
public class SampleStatistic
|
||||||
{
|
{
|
||||||
protected final LongAccumulator _max = new LongAccumulator(Math::max,0L);
|
private final LongAccumulator _max = new LongAccumulator(Math::max, 0L);
|
||||||
protected final AtomicLong _total = new AtomicLong();
|
private final AtomicLong _total = new AtomicLong();
|
||||||
protected final AtomicLong _count = new AtomicLong();
|
private final AtomicLong _count = new AtomicLong();
|
||||||
protected final LongAdder _totalVariance100 = new LongAdder();
|
private final LongAdder _totalVariance100 = new LongAdder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the statistics.
|
||||||
|
*/
|
||||||
public void reset()
|
public void reset()
|
||||||
{
|
{
|
||||||
_max.reset();
|
_max.reset();
|
||||||
|
@ -55,61 +50,89 @@ public class SampleStatistic
|
||||||
_totalVariance100.reset();
|
_totalVariance100.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(final long sample)
|
/**
|
||||||
|
* Records a sample value.
|
||||||
|
*
|
||||||
|
* @param sample the value to record.
|
||||||
|
*/
|
||||||
|
public void record(long sample)
|
||||||
{
|
{
|
||||||
long total = _total.addAndGet(sample);
|
long total = _total.addAndGet(sample);
|
||||||
long count = _count.incrementAndGet();
|
long count = _count.incrementAndGet();
|
||||||
|
|
||||||
if (count>1)
|
if (count > 1)
|
||||||
{
|
{
|
||||||
long mean10 = total*10/count;
|
long mean10 = total * 10 / count;
|
||||||
long delta10 = sample*10 - mean10;
|
long delta10 = sample * 10 - mean10;
|
||||||
_totalVariance100.add(delta10*delta10);
|
_totalVariance100.add(delta10 * delta10);
|
||||||
}
|
}
|
||||||
|
|
||||||
_max.accumulate(sample);
|
_max.accumulate(sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the max value
|
* @deprecated use {@link #record(long)} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void set(long sample)
|
||||||
|
{
|
||||||
|
record(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the max value of the recorded samples
|
||||||
*/
|
*/
|
||||||
public long getMax()
|
public long getMax()
|
||||||
{
|
{
|
||||||
return _max.get();
|
return _max.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sum of all the recorded samples
|
||||||
|
*/
|
||||||
public long getTotal()
|
public long getTotal()
|
||||||
{
|
{
|
||||||
return _total.get();
|
return _total.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the number of samples recorded
|
||||||
|
*/
|
||||||
public long getCount()
|
public long getCount()
|
||||||
{
|
{
|
||||||
return _count.get();
|
return _count.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the average value of the samples recorded, or zero if there are no samples
|
||||||
|
*/
|
||||||
public double getMean()
|
public double getMean()
|
||||||
{
|
{
|
||||||
return (double)_total.get()/_count.get();
|
long count = getCount();
|
||||||
|
return count > 0 ? (double)_total.get() / _count.get() : 0.0D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the variance of the samples recorded, or zero if there are less than 2 samples
|
||||||
|
*/
|
||||||
public double getVariance()
|
public double getVariance()
|
||||||
{
|
{
|
||||||
final long variance100 = _totalVariance100.sum();
|
long variance100 = _totalVariance100.sum();
|
||||||
final long count = _count.get();
|
long count = getCount();
|
||||||
|
return count > 1 ? variance100 / 100.0D / (count - 1) : 0.0D;
|
||||||
return count>1?((double)variance100)/100.0/(count-1):0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the standard deviation of the samples recorded
|
||||||
|
*/
|
||||||
public double getStdDev()
|
public double getStdDev()
|
||||||
{
|
{
|
||||||
return Math.sqrt(getVariance());
|
return Math.sqrt(getVariance());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return String.format("%s@%x{c=%d,m=%d,t=%d,v100=%d}",this.getClass().getSimpleName(),hashCode(),_count.get(),_max.get(),_total.get(),_totalVariance100.sum());
|
return String.format("%s@%x{count=%d,mean=%d,total=%d,stddev=%f}", getClass().getSimpleName(), hashCode(), getCount(), getMax(), getTotal(), getStdDev());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.util.statistic;
|
package org.eclipse.jetty.util.statistic;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
public class SampleStatisticTest
|
public class SampleStatisticTest
|
||||||
|
@ -55,12 +55,13 @@ public class SampleStatisticTest
|
||||||
{
|
{
|
||||||
stats.reset();
|
stats.reset();
|
||||||
for (long x : data[d])
|
for (long x : data[d])
|
||||||
stats.set(x);
|
stats.record(x);
|
||||||
|
|
||||||
assertEquals("count"+d,data[d].length, (int)stats.getCount());
|
assertEquals("count"+d,data[d].length, (int)stats.getCount());
|
||||||
assertNearEnough("mean"+d,results[d][0], stats.getMean());
|
assertNearEnough("mean"+d,results[d][0], stats.getMean());
|
||||||
assertNearEnough("stddev"+d,results[d][1], stats.getStdDev());
|
assertNearEnough("stddev"+d,results[d][1], stats.getStdDev());
|
||||||
}
|
}
|
||||||
|
System.err.println(stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertNearEnough(String test,double expected, double actual)
|
private void assertNearEnough(String test,double expected, double actual)
|
||||||
|
|
Loading…
Reference in New Issue