Skip to content

Commit

Permalink
Issue #5783 - fix getRate() methods on ConnectionStatistics
Browse files Browse the repository at this point in the history
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
  • Loading branch information
lachlan-roberts committed Dec 10, 2020
1 parent e49d011 commit ffe3aa4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 40 deletions.
Expand Up @@ -19,16 +19,14 @@
package org.eclipse.jetty.io;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.RateCounter;
import org.eclipse.jetty.util.statistic.SampleStatistic;

/**
Expand All @@ -43,28 +41,20 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio
{
private final CounterStatistic _connections = new CounterStatistic();
private final SampleStatistic _connectionsDuration = new SampleStatistic();
private final LongAdder _rcvdBytes = new LongAdder();
private final AtomicLong _bytesInStamp = new AtomicLong();
private final LongAdder _sentBytes = new LongAdder();
private final AtomicLong _bytesOutStamp = new AtomicLong();
private final LongAdder _messagesIn = new LongAdder();
private final AtomicLong _messagesInStamp = new AtomicLong();
private final LongAdder _messagesOut = new LongAdder();
private final AtomicLong _messagesOutStamp = new AtomicLong();
private final RateCounter _bytesIn = new RateCounter();
private final RateCounter _bytesOut = new RateCounter();
private final RateCounter _messagesIn = new RateCounter();
private final RateCounter _messagesOut = new RateCounter();

@ManagedOperation(value = "Resets the statistics", impact = "ACTION")
public void reset()
{
_connections.reset();
_connectionsDuration.reset();
_rcvdBytes.reset();
_bytesInStamp.set(System.nanoTime());
_sentBytes.reset();
_bytesOutStamp.set(System.nanoTime());
_bytesIn.reset();
_bytesOut.reset();
_messagesIn.reset();
_messagesInStamp.set(System.nanoTime());
_messagesOut.reset();
_messagesOutStamp.set(System.nanoTime());
}

@Override
Expand All @@ -89,20 +79,20 @@ public void onClosed(Connection connection)
return;

_connections.decrement();

long elapsed = System.currentTimeMillis() - connection.getCreatedTimeStamp();
_connectionsDuration.record(elapsed);
_connectionsDuration.record(System.currentTimeMillis() - connection.getCreatedTimeStamp());

long bytesIn = connection.getBytesIn();
if (bytesIn > 0)
_rcvdBytes.add(bytesIn);
_bytesIn.add(bytesIn);

long bytesOut = connection.getBytesOut();
if (bytesOut > 0)
_sentBytes.add(bytesOut);
_bytesOut.add(bytesOut);

long messagesIn = connection.getMessagesIn();
if (messagesIn > 0)
_messagesIn.add(messagesIn);

long messagesOut = connection.getMessagesOut();
if (messagesOut > 0)
_messagesOut.add(messagesOut);
Expand All @@ -111,31 +101,25 @@ public void onClosed(Connection connection)
@ManagedAttribute("Total number of bytes received by tracked connections")
public long getReceivedBytes()
{
return _rcvdBytes.sum();
return _bytesIn.sum();
}

@ManagedAttribute("Total number of bytes received per second since the last invocation of this method")
public long getReceivedBytesRate()
{
long now = System.nanoTime();
long then = _bytesInStamp.getAndSet(now);
long elapsed = TimeUnit.NANOSECONDS.toMillis(now - then);
return elapsed == 0 ? 0 : getReceivedBytes() * 1000 / elapsed;
return _bytesIn.getRate();
}

@ManagedAttribute("Total number of bytes sent by tracked connections")
public long getSentBytes()
{
return _sentBytes.sum();
return _bytesOut.sum();
}

@ManagedAttribute("Total number of bytes sent per second since the last invocation of this method")
public long getSentBytesRate()
{
long now = System.nanoTime();
long then = _bytesOutStamp.getAndSet(now);
long elapsed = TimeUnit.NANOSECONDS.toMillis(now - then);
return elapsed == 0 ? 0 : getSentBytes() * 1000 / elapsed;
return _bytesOut.getRate();
}

@ManagedAttribute("The max duration of a connection in ms")
Expand Down Expand Up @@ -183,10 +167,7 @@ public long getReceivedMessages()
@ManagedAttribute("Total number of messages received per second since the last invocation of this method")
public long getReceivedMessagesRate()
{
long now = System.nanoTime();
long then = _messagesInStamp.getAndSet(now);
long elapsed = TimeUnit.NANOSECONDS.toMillis(now - then);
return elapsed == 0 ? 0 : getReceivedMessages() * 1000 / elapsed;
return _messagesIn.getRate();
}

@ManagedAttribute("The total number of messages sent")
Expand All @@ -198,10 +179,7 @@ public long getSentMessages()
@ManagedAttribute("Total number of messages sent per second since the last invocation of this method")
public long getSentMessagesRate()
{
long now = System.nanoTime();
long then = _messagesOutStamp.getAndSet(now);
long elapsed = TimeUnit.NANOSECONDS.toMillis(now - then);
return elapsed == 0 ? 0 : getSentMessages() * 1000 / elapsed;
return _messagesOut.getRate();
}

@Override
Expand Down
@@ -0,0 +1,61 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//

package org.eclipse.jetty.util.statistic;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

/**
* Gives the same basic functionality of {@link LongAdder} but allows you to check
* the rate of increase of the sum since the last call to {@link #getRate()};
*/
public class RateCounter
{
private final LongAdder _total = new LongAdder();
private final LongAdder _totalSinceRateCheck = new LongAdder();
private final AtomicLong _rateCheckTimeStamp = new AtomicLong();

public long sum()
{
return _total.sum();
}

public void add(long l)
{
_total.add(l);
_totalSinceRateCheck.add(l);
}

public void reset()
{
_rateCheckTimeStamp.getAndSet(System.nanoTime());
_totalSinceRateCheck.reset();
_total.reset();
}

public long getRate()
{
long totalSinceLastCheck = _totalSinceRateCheck.sumThenReset();
long now = System.nanoTime();
long then = _rateCheckTimeStamp.getAndSet(now);
long elapsed = TimeUnit.NANOSECONDS.toMillis(now - then);
return elapsed == 0 ? 0 : totalSinceLastCheck * 1000 / elapsed;
}
}

0 comments on commit ffe3aa4

Please sign in to comment.