Skip to content

Commit

Permalink
#9145 cleanup stats
Browse files Browse the repository at this point in the history
Signed-off-by: Ludovic Orban <[email protected]>
  • Loading branch information
lorban committed Feb 6, 2023
1 parent 5cc0799 commit 7734327
Show file tree
Hide file tree
Showing 10 changed files with 31 additions and 2,934 deletions.
6 changes: 3 additions & 3 deletions jetty-core/jetty-server/src/main/config/etc/jetty-stats.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
<!-- =============================================================== -->

<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- Collects request stats -->
<Call name="insertHandler">
<Arg>
<New id="StatsHandler" class="org.eclipse.jetty.server.handler.StatisticsHandler">
<Set name="gracefulShutdownWaitsForRequests"><Property name="jetty.statistics.gracefulShutdownWaitsForRequests" default="true"/></Set>
</New>
<New id="StatsHandler" class="org.eclipse.jetty.server.handler.StatisticsHandler"/>
</Arg>
</Call>
<!-- Collects connection stats -->
<Call name="addBeanToAllConnectors">
<Arg>
<New class="org.eclipse.jetty.io.ConnectionStatistics"/>
Expand Down
14 changes: 1 addition & 13 deletions jetty-core/jetty-server/src/main/config/modules/stats.mod
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html

[description]
Enables detailed statistics collection for the server.
Enables statistics collection for the server.

[tags]
server

[depend]
server
servlet

[lib]
lib/jetty-util-ajax-${jetty.version}.jar

[xml]
etc/jetty-stats.xml

[ini]
jetty.webapp.addServerClasses+=,-org.eclipse.jetty.ee9.servlet.StatisticsServlet

[ini-template]

## If the Graceful shutdown should wait for async requests as well as the currently dispatched ones.
# jetty.statistics.gracefulShutdownWaitsForRequests=true
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.LongAdder;

import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpStream;
Expand All @@ -33,23 +30,21 @@
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedOperation;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.DumpableCollection;
import org.eclipse.jetty.util.statistic.CounterStatistic;
import org.eclipse.jetty.util.statistic.SampleStatistic;

public class StatisticsHandler extends Handler.BaseWrapper
{
private final Set<String> _connectionStats = ConcurrentHashMap.newKeySet();
private final CounterStatistic _requestStats = new CounterStatistic();
private final CounterStatistic _processStats = new CounterStatistic();
private final SampleStatistic _requestTimeStats = new SampleStatistic();
private final SampleStatistic _processTimeStats = new SampleStatistic();
private final CounterStatistic _requestStats = new CounterStatistic(); // how many requests are being processed (full lifecycle)
private final SampleStatistic _requestTimeStats = new SampleStatistic(); // latencies of requests (full lifecycle)
private final LongAdder _processingErrors = new LongAdder();
private final LongAdder _responses1xx = new LongAdder();
private final LongAdder _responses2xx = new LongAdder();
private final LongAdder _responses3xx = new LongAdder();
private final LongAdder _responses4xx = new LongAdder();
private final LongAdder _responses5xx = new LongAdder();
private final LongAdder _bytesRead = new LongAdder();
private final LongAdder _bytesWritten = new LongAdder();

@Override
public boolean process(Request request, Response response, Callback callback) throws Exception
Expand All @@ -58,16 +53,9 @@ public boolean process(Request request, Response response, Callback callback) th
if (next == null)
return false;

StatisticsRequest statisticsRequest = newStatisticsRequest(request);
Request statisticsRequest = newStatisticsRequest(request);
try
{
_processStats.increment();
_requestStats.increment();

String id = statisticsRequest.getConnectionMetaData().getId();
if (_connectionStats.add(id))
statisticsRequest.getConnectionMetaData().getConnection().addEventListener(statisticsRequest);

if (next.process(statisticsRequest, response, callback))
return true;
_requestStats.decrement();
Expand All @@ -78,50 +66,43 @@ public boolean process(Request request, Response response, Callback callback) th
_processingErrors.increment();
throw t;
}
finally
{
_processStats.decrement();
_processTimeStats.record(NanoTime.since(statisticsRequest._startProcessingNanoTime));
}
}

@Override
public void dump(Appendable out, String indent) throws IOException
{
dumpObjects(out, indent,
new DumpableCollection("connectionStats", _connectionStats),
Dumpable.named("requestStats", _requestStats),
Dumpable.named("requestTimeStats", _requestTimeStats),
Dumpable.named("processStats", _processStats),
Dumpable.named("processTimeStats", _processTimeStats),
Dumpable.named("processingErrors", _processingErrors),
Dumpable.named("1xxResponses", _responses1xx),
Dumpable.named("2xxResponses", _responses2xx),
Dumpable.named("3xxResponses", _responses3xx),
Dumpable.named("4xxResponses", _responses4xx),
Dumpable.named("5xxResponses", _responses5xx)
Dumpable.named("5xxResponses", _responses5xx),
Dumpable.named("bytesRead", _bytesRead),
Dumpable.named("bytesWritten", _bytesWritten)
);
}

protected StatisticsRequest newStatisticsRequest(Request request)
protected Request newStatisticsRequest(Request request)
{
return new StatisticsRequest(request);
}

@ManagedOperation(value = "resets the statistics", impact = "ACTION")
public void reset()
{
_connectionStats.clear();
_requestStats.reset();
_processStats.reset();
_requestTimeStats.reset();
_processTimeStats.reset();
_processingErrors.reset();
_responses1xx.reset();
_responses2xx.reset();
_responses3xx.reset();
_responses4xx.reset();
_responses5xx.reset();
_bytesRead.reset();
_bytesWritten.reset();
}

@ManagedAttribute("number of requests")
Expand Down Expand Up @@ -178,24 +159,6 @@ public int getProcessingErrors()
return _processingErrors.intValue();
}

@ManagedAttribute("")
public int getProcessings()
{
return (int)_processStats.getTotal();
}

@ManagedAttribute("")
public int getProcessingsActive()
{
return (int)_processStats.getCurrent();
}

@ManagedAttribute("")
public int getProcessingsMax()
{
return (int)_processStats.getMax();
}

@ManagedAttribute("total time spend in all request execution (in ns)")
public long getRequestTimeTotal()
{
Expand All @@ -220,96 +183,37 @@ public double getRequestTimeStdDev()
return _requestTimeStats.getStdDev();
}

@ManagedAttribute("(in ns)")
public long getProcessingTimeTotal()
{
return _processTimeStats.getTotal();
}

@ManagedAttribute("(in ns)")
public long getProcessingTimeMax()
@ManagedAttribute("bytes read count")
public long getBytesRead()
{
return _processTimeStats.getMax();
return _bytesRead.longValue();
}

@ManagedAttribute("(in ns)")
public double getProcessingTimeMean()
@ManagedAttribute("bytes written count")
public long getBytesWritten()
{
return _processTimeStats.getMean();
return _bytesWritten.longValue();
}

@ManagedAttribute("(in ns)")
public double getProcessingTimeStdDev()
private class StatisticsRequest extends Request.Wrapper
{
return _processTimeStats.getStdDev();
}

private class StatisticsRequest extends Request.Wrapper implements Connection.Listener
{
private final LongAdder _bytesRead = new LongAdder();
private final LongAdder _bytesWritten = new LongAdder();
private final long _startProcessingNanoTime;

private StatisticsRequest(Request request)
{
super(request);
_startProcessingNanoTime = NanoTime.now();
addHttpStreamWrapper(this::asHttpStream);

}

public LongAdder getBytesRead()
{
return _bytesRead;
}

public LongAdder getBytesWritten()
{
return _bytesWritten;
}

@Override
public void onClosed(Connection connection)
{
_connectionStats.remove(getConnectionMetaData().getId());
}

public HttpStream asHttpStream(HttpStream httpStream)
{
return new StatisticsHttpStream(httpStream);
}

@Override
public Object getAttribute(String name)
{
// return hidden attributes for requestLog
return switch (name)
{
// TODO class.getName + extra
case "o.e.j.s.h.StatsHandler.bytesRead" -> _bytesRead.longValue();
case "o.e.j.s.h.StatsHandler.bytesWritten" -> _bytesWritten.longValue();
case "o.e.j.s.h.StatsHandler.spentTime" -> spentTimeNs();
case "o.e.j.s.h.StatsHandler.dataReadRate" -> dataRatePerSecond(_bytesRead.longValue());
case "o.e.j.s.h.StatsHandler.dataWriteRate" -> dataRatePerSecond(_bytesWritten.longValue());
default -> super.getAttribute(name);
};
}

protected long dataRatePerSecond(long dataCount)
{
return (long)(dataCount / (spentTimeNs() / 1_000_000_000F));
}

private long spentTimeNs()
{
return NanoTime.since(getNanoTime());
}

protected class StatisticsHttpStream extends HttpStream.Wrapper
{
public StatisticsHttpStream(HttpStream httpStream)
{
super(httpStream);
_requestStats.increment();
}

@Override
Expand Down Expand Up @@ -338,7 +242,6 @@ public void send(MetaData.Request request, MetaData.Response response, boolean l
int length = BufferUtil.length(content);
if (length > 0)
_bytesWritten.add(length);

super.send(request, response, last, content, callback);
}

Expand All @@ -360,7 +263,7 @@ public void failed(Throwable x)
}
}

static class MinimumDataRateHandler extends StatisticsHandler
public static class MinimumDataRateHandler extends StatisticsHandler
{
private final long _minimumReadRate;
private final long _minimumWriteRate;
Expand All @@ -386,15 +289,19 @@ private MinimumDataRateRequest(Request request)
super(request);
}

private long dataRatePerSecond(long dataCount)
{
return (long)(dataCount / (NanoTime.since(getNanoTime()) / 1_000_000_000F));
}

@Override
public void demand(Runnable demandCallback)
{
if (_minimumReadRate > 0)
{
long rr = dataRatePerSecond(getBytesRead().longValue());
long rr = dataRatePerSecond(getBytesRead());
if (rr < _minimumReadRate)
{
// TODO should this be a QuietException to reduce log verbosity from bad clients?
_errorContent = Content.Chunk.from(new TimeoutException("read rate is too low: " + rr));
demandCallback.run();
return;
Expand All @@ -419,7 +326,7 @@ public void send(MetaData.Request request, MetaData.Response response, boolean l
{
if (_minimumWriteRate > 0)
{
long bytesWritten = getBytesWritten().longValue();
long bytesWritten = getBytesWritten();
if (bytesWritten > 0L)
{
long wr = dataRatePerSecond(bytesWritten);
Expand Down
Loading

0 comments on commit 7734327

Please sign in to comment.