
org.eclipse.jetty.io.ConnectionStatistics Maven / Gradle / Ivy
//
// ========================================================================
// Copyright (c) 1995-2022 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.io;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
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;
/**
* A {@link Connection.Listener} that tracks connection statistics.
* Adding an instance of this class as a bean to a ServerConnector
* or ConnectionFactory (for the server) or to HttpClient (for the client)
* will trigger the tracking of the connection statistics for all
* connections managed by the server or by the client.
* The statistics for a connection are gathered when the connection
* is closed.
* ConnectionStatistics instances must be {@link #start() started}
* to collect statistics, either as part of starting the whole component
* tree, or explicitly if the component tree has already been started.
*
* @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
*/
@ManagedObject("Tracks statistics on connections")
@Deprecated(since = "2021-05-27")
public class ConnectionStatistics extends AbstractLifeCycle implements Connection.Listener, Dumpable {
private final Stats _stats = new Stats("total");
private final Map _statsMap = new ConcurrentHashMap<>();
@ManagedOperation(value = "Resets the statistics", impact = "ACTION")
public void reset() {
_stats.reset();
_statsMap.clear();
}
@Override
protected void doStart() throws Exception {
reset();
}
@Override
public void onOpened(Connection connection) {
if (!isStarted())
return;
onTotalOpened(connection);
onConnectionOpened(connection);
}
protected void onTotalOpened(Connection connection) {
_stats.incrementCount();
}
protected void onConnectionOpened(Connection connection) {
_statsMap.computeIfAbsent(connection.getClass().getName(), Stats::new).incrementCount();
}
@Override
public void onClosed(Connection connection) {
if (!isStarted())
return;
onTotalClosed(connection);
onConnectionClosed(connection);
}
protected void onTotalClosed(Connection connection) {
onClosed(_stats, connection);
}
protected void onConnectionClosed(Connection connection) {
Stats stats = _statsMap.get(connection.getClass().getName());
if (stats != null)
onClosed(stats, connection);
}
private void onClosed(Stats stats, Connection connection) {
stats.decrementCount();
stats.recordDuration(System.currentTimeMillis() - connection.getCreatedTimeStamp());
long bytesIn = connection.getBytesIn();
if (bytesIn > 0)
stats.recordBytesIn(bytesIn);
long bytesOut = connection.getBytesOut();
if (bytesOut > 0)
stats.recordBytesOut(bytesOut);
long messagesIn = connection.getMessagesIn();
if (messagesIn > 0)
stats.recordMessagesIn(messagesIn);
long messagesOut = connection.getMessagesOut();
if (messagesOut > 0)
stats.recordMessagesOut(messagesOut);
}
@ManagedAttribute("Total number of bytes received by tracked connections")
public long getReceivedBytes() {
return _stats.getReceivedBytes();
}
@ManagedAttribute("Total number of bytes received per second since the last invocation of this method")
public long getReceivedBytesRate() {
return _stats.getReceivedBytesRate();
}
@ManagedAttribute("Total number of bytes sent by tracked connections")
public long getSentBytes() {
return _stats.getSentBytes();
}
@ManagedAttribute("Total number of bytes sent per second since the last invocation of this method")
public long getSentBytesRate() {
return _stats.getSentBytesRate();
}
@ManagedAttribute("The max duration of a connection in ms")
public long getConnectionDurationMax() {
return _stats.getConnectionDurationMax();
}
@ManagedAttribute("The mean duration of a connection in ms")
public double getConnectionDurationMean() {
return _stats.getConnectionDurationMean();
}
@ManagedAttribute("The standard deviation of the duration of a connection")
public double getConnectionDurationStdDev() {
return _stats.getConnectionDurationStdDev();
}
@ManagedAttribute("The total number of connections opened")
public long getConnectionsTotal() {
return _stats.getConnectionsTotal();
}
@ManagedAttribute("The current number of open connections")
public long getConnections() {
return _stats.getConnections();
}
@ManagedAttribute("The max number of open connections")
public long getConnectionsMax() {
return _stats.getConnectionsMax();
}
@ManagedAttribute("The total number of messages received")
public long getReceivedMessages() {
return _stats.getReceivedMessages();
}
@ManagedAttribute("Total number of messages received per second since the last invocation of this method")
public long getReceivedMessagesRate() {
return _stats.getReceivedMessagesRate();
}
@ManagedAttribute("The total number of messages sent")
public long getSentMessages() {
return _stats.getSentMessages();
}
@ManagedAttribute("Total number of messages sent per second since the last invocation of this method")
public long getSentMessagesRate() {
return _stats.getSentMessagesRate();
}
public Map getConnectionStatisticsGroups() {
return _statsMap;
}
@Override
public void dump(Appendable out, String indent) throws IOException {
List children = new ArrayList<>();
children.add(_stats);
children.addAll(_statsMap.values());
Dumpable.dumpObjects(out, indent, this, children.toArray());
}
@Override
public String toString() {
return String.format("%s@%x", getClass().getSimpleName(), hashCode());
}
// @deprecated The Eclipse Jetty and Apache Felix Http Jetty packages are no longer supported.
@Deprecated(since = "2021-05-27")
public static class Stats implements Dumpable {
private final CounterStatistic _connections = new CounterStatistic();
private final SampleStatistic _connectionsDuration = new SampleStatistic();
private final LongAdder _bytesIn = new LongAdder();
private final RateCounter _bytesInRate = new RateCounter();
private final LongAdder _bytesOut = new LongAdder();
private final RateCounter _bytesOutRate = new RateCounter();
private final LongAdder _messagesIn = new LongAdder();
private final RateCounter _messagesInRate = new RateCounter();
private final LongAdder _messagesOut = new LongAdder();
private final RateCounter _messagesOutRate = new RateCounter();
private final String _name;
public Stats(String name) {
_name = name;
}
public void reset() {
_connections.reset();
_connectionsDuration.reset();
_bytesIn.reset();
_bytesInRate.reset();
_bytesOut.reset();
_bytesOutRate.reset();
_messagesIn.reset();
_messagesInRate.reset();
_messagesOut.reset();
_messagesOutRate.reset();
}
public String getName() {
return _name;
}
public long getReceivedBytes() {
return _bytesIn.sum();
}
public long getReceivedBytesRate() {
long rate = _bytesInRate.getRate();
_bytesInRate.reset();
return rate;
}
public long getSentBytes() {
return _bytesOut.sum();
}
public long getSentBytesRate() {
long rate = _bytesOutRate.getRate();
_bytesOutRate.reset();
return rate;
}
public long getConnectionDurationMax() {
return _connectionsDuration.getMax();
}
public double getConnectionDurationMean() {
return _connectionsDuration.getMean();
}
public double getConnectionDurationStdDev() {
return _connectionsDuration.getStdDev();
}
public long getConnectionsTotal() {
return _connections.getTotal();
}
public long getConnections() {
return _connections.getCurrent();
}
public long getConnectionsMax() {
return _connections.getMax();
}
public long getReceivedMessages() {
return _messagesIn.sum();
}
public long getReceivedMessagesRate() {
long rate = _messagesInRate.getRate();
_messagesInRate.reset();
return rate;
}
public long getSentMessages() {
return _messagesOut.sum();
}
public long getSentMessagesRate() {
long rate = _messagesOutRate.getRate();
_messagesOutRate.reset();
return rate;
}
public void incrementCount() {
_connections.increment();
}
public void decrementCount() {
_connections.decrement();
}
public void recordDuration(long duration) {
_connectionsDuration.record(duration);
}
public void recordBytesIn(long bytesIn) {
_bytesIn.add(bytesIn);
_bytesInRate.add(bytesIn);
}
public void recordBytesOut(long bytesOut) {
_bytesOut.add(bytesOut);
_bytesOutRate.add(bytesOut);
}
public void recordMessagesIn(long messagesIn) {
_messagesIn.add(messagesIn);
_messagesInRate.add(messagesIn);
}
public void recordMessagesOut(long messagesOut) {
_messagesOut.add(messagesOut);
_messagesOutRate.add(messagesOut);
}
@Override
public void dump(Appendable out, String indent) throws IOException {
Dumpable.dumpObjects(out, indent, this, String.format("connections=%s", _connections), String.format("durations=%s", _connectionsDuration), String.format("bytes in/out=%s/%s", getReceivedBytes(), getSentBytes()), String.format("messages in/out=%s/%s", getReceivedMessages(), getSentMessages()));
}
@Override
public String toString() {
return String.format("%s[%s]", getClass().getSimpleName(), getName());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy