From ffe3aa4459c25b3db142b0465699f027e143dd6a Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 10 Dec 2020 22:15:59 +1100 Subject: [PATCH 1/3] Issue #5783 - fix getRate() methods on ConnectionStatistics Signed-off-by: Lachlan Roberts --- .../jetty/io/ConnectionStatistics.java | 58 ++++++------------ .../jetty/util/statistic/RateCounter.java | 61 +++++++++++++++++++ 2 files changed, 79 insertions(+), 40 deletions(-) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java index 9fbbb884bea..966118517f6 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java @@ -19,9 +19,6 @@ 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; @@ -29,6 +26,7 @@ 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; /** @@ -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 @@ -89,20 +79,20 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio 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); @@ -111,31 +101,25 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio @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") @@ -183,10 +167,7 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio @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") @@ -198,10 +179,7 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio @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 diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java new file mode 100644 index 00000000000..f37c76a62ef --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java @@ -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; + } +} From 8a940fc18111daf11e4965a12c3e330b1f694267 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Thu, 10 Dec 2020 22:22:31 +1100 Subject: [PATCH 2/3] Issue #5783 - start _rateCheckTimeStamp at current time Signed-off-by: Lachlan Roberts --- .../main/java/org/eclipse/jetty/util/statistic/RateCounter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java index f37c76a62ef..660597577b0 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java @@ -30,7 +30,7 @@ public class RateCounter { private final LongAdder _total = new LongAdder(); private final LongAdder _totalSinceRateCheck = new LongAdder(); - private final AtomicLong _rateCheckTimeStamp = new AtomicLong(); + private final AtomicLong _rateCheckTimeStamp = new AtomicLong(System.nanoTime()); public long sum() { From 4e9e9b8d19fe58be4be041d0d516cf3384ddd0b2 Mon Sep 17 00:00:00 2001 From: Lachlan Roberts Date: Mon, 21 Dec 2020 15:55:54 +1100 Subject: [PATCH 3/3] Remove the total count from the RateCounter. Signed-off-by: Lachlan Roberts --- .../jetty/io/ConnectionStatistics.java | 46 +++++++++++++++---- .../jetty/util/statistic/RateCounter.java | 32 ++++--------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java index 966118517f6..3e4b448ca16 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ConnectionStatistics.java @@ -19,6 +19,7 @@ package org.eclipse.jetty.io; import java.io.IOException; +import java.util.concurrent.atomic.LongAdder; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; @@ -41,10 +42,15 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio { private final CounterStatistic _connections = new CounterStatistic(); private final SampleStatistic _connectionsDuration = new SampleStatistic(); - private final RateCounter _bytesIn = new RateCounter(); - private final RateCounter _bytesOut = new RateCounter(); - private final RateCounter _messagesIn = new RateCounter(); - private final RateCounter _messagesOut = new RateCounter(); + + private final LongAdder _bytesIn = new LongAdder(); + private final LongAdder _bytesOut = new LongAdder(); + private final LongAdder _messagesIn = new LongAdder(); + private final LongAdder _messagesOut = new LongAdder(); + private final RateCounter _bytesInRate = new RateCounter(); + private final RateCounter _bytesOutRate = new RateCounter(); + private final RateCounter _messagesInRate = new RateCounter(); + private final RateCounter _messagesOutRate = new RateCounter(); @ManagedOperation(value = "Resets the statistics", impact = "ACTION") public void reset() @@ -55,6 +61,10 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio _bytesOut.reset(); _messagesIn.reset(); _messagesOut.reset(); + _bytesInRate.reset(); + _bytesOutRate.reset(); + _messagesInRate.reset(); + _messagesOutRate.reset(); } @Override @@ -83,19 +93,31 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio long bytesIn = connection.getBytesIn(); if (bytesIn > 0) + { _bytesIn.add(bytesIn); + _bytesInRate.add(bytesIn); + } long bytesOut = connection.getBytesOut(); if (bytesOut > 0) + { _bytesOut.add(bytesOut); + _bytesOutRate.add(bytesOut); + } long messagesIn = connection.getMessagesIn(); if (messagesIn > 0) + { _messagesIn.add(messagesIn); + _messagesInRate.add(messagesIn); + } long messagesOut = connection.getMessagesOut(); if (messagesOut > 0) + { _messagesOut.add(messagesOut); + _messagesOutRate.add(messagesOut); + } } @ManagedAttribute("Total number of bytes received by tracked connections") @@ -107,7 +129,9 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio @ManagedAttribute("Total number of bytes received per second since the last invocation of this method") public long getReceivedBytesRate() { - return _bytesIn.getRate(); + long rate = _bytesInRate.getRate(); + _bytesInRate.reset(); + return rate; } @ManagedAttribute("Total number of bytes sent by tracked connections") @@ -119,7 +143,9 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio @ManagedAttribute("Total number of bytes sent per second since the last invocation of this method") public long getSentBytesRate() { - return _bytesOut.getRate(); + long rate = _bytesOutRate.getRate(); + _bytesOutRate.reset(); + return rate; } @ManagedAttribute("The max duration of a connection in ms") @@ -167,7 +193,9 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio @ManagedAttribute("Total number of messages received per second since the last invocation of this method") public long getReceivedMessagesRate() { - return _messagesIn.getRate(); + long rate = _messagesInRate.getRate(); + _messagesInRate.reset(); + return rate; } @ManagedAttribute("The total number of messages sent") @@ -179,7 +207,9 @@ public class ConnectionStatistics extends AbstractLifeCycle implements Connectio @ManagedAttribute("Total number of messages sent per second since the last invocation of this method") public long getSentMessagesRate() { - return _messagesOut.getRate(); + long rate = _messagesOutRate.getRate(); + _messagesOutRate.reset(); + return rate; } @Override diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java index 660597577b0..2de5f10797d 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/statistic/RateCounter.java @@ -23,39 +23,27 @@ 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()}; + * Counts the rate that {@link Long}s are added to this from the time of creation or the last call to {@link #reset()}. */ public class RateCounter { private final LongAdder _total = new LongAdder(); - private final LongAdder _totalSinceRateCheck = new LongAdder(); - private final AtomicLong _rateCheckTimeStamp = new AtomicLong(System.nanoTime()); - - public long sum() - { - return _total.sum(); - } + private final AtomicLong _timeStamp = new AtomicLong(System.nanoTime()); 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; + long elapsed = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - _timeStamp.get()); + return elapsed == 0 ? 0 : _total.sum() * 1000 / elapsed; + } + + public void reset() + { + _timeStamp.getAndSet(System.nanoTime()); + _total.reset(); } }