X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fserver%2FConnectorStatistics.java;fp=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Fserver%2FConnectorStatistics.java;h=cae5e6eb350ade3b95dbbeb4308df34dcd1d0fe9;hp=0000000000000000000000000000000000000000;hb=73ef54a38e3930a1a789cdc6b5fa23cdd4c9d086;hpb=515007c7c1351045420669d65b59c08fa46850f2 diff --git a/lib/jetty/org/eclipse/jetty/server/ConnectorStatistics.java b/lib/jetty/org/eclipse/jetty/server/ConnectorStatistics.java new file mode 100644 index 00000000..cae5e6eb --- /dev/null +++ b/lib/jetty/org/eclipse/jetty/server/ConnectorStatistics.java @@ -0,0 +1,308 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// 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.server; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import org.eclipse.jetty.io.Connection; +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.Container; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.component.Dumpable; +import org.eclipse.jetty.util.statistic.CounterStatistic; +import org.eclipse.jetty.util.statistic.SampleStatistic; + + +/* ------------------------------------------------------------ */ +/** A Connector.Listener that gathers Connector and Connections Statistics. + * Adding an instance of this class as with {@link AbstractConnector#addBean(Object)} + * will register the listener with all connections accepted by that connector. + */ +@ManagedObject("Connector Statistics") +public class ConnectorStatistics extends AbstractLifeCycle implements Dumpable, Connection.Listener +{ + private final static Sample ZERO=new Sample(); + private final AtomicLong _startMillis = new AtomicLong(-1L); + private final CounterStatistic _connectionStats = new CounterStatistic(); + private final SampleStatistic _messagesIn = new SampleStatistic(); + private final SampleStatistic _messagesOut = new SampleStatistic(); + private final SampleStatistic _connectionDurationStats = new SampleStatistic(); + private final ConcurrentMap _samples = new ConcurrentHashMap<>(); + private final AtomicInteger _closedIn = new AtomicInteger(); + private final AtomicInteger _closedOut = new AtomicInteger(); + private AtomicLong _nanoStamp=new AtomicLong(); + private volatile int _messagesInPerSecond; + private volatile int _messagesOutPerSecond; + + @Override + public void onOpened(Connection connection) + { + if (isStarted()) + { + _connectionStats.increment(); + _samples.put(connection,ZERO); + } + } + + @Override + public void onClosed(Connection connection) + { + if (isStarted()) + { + int msgsIn=connection.getMessagesIn(); + int msgsOut=connection.getMessagesOut(); + _messagesIn.set(msgsIn); + _messagesOut.set(msgsOut); + _connectionStats.decrement(); + _connectionDurationStats.set(System.currentTimeMillis()-connection.getCreatedTimeStamp()); + + Sample sample=_samples.remove(connection); + if (sample!=null) + { + _closedIn.addAndGet(msgsIn-sample._messagesIn); + _closedOut.addAndGet(msgsOut-sample._messagesOut); + } + } + } + + @ManagedAttribute("Total number of bytes received by this connector") + public int getBytesIn() + { + // TODO + return -1; + } + + @ManagedAttribute("Total number of bytes sent by this connector") + public int getBytesOut() + { + // TODO + return -1; + } + + @ManagedAttribute("Total number of connections seen by this connector") + public int getConnections() + { + return (int)_connectionStats.getTotal(); + } + + @ManagedAttribute("Connection duration maximum in ms") + public long getConnectionDurationMax() + { + return _connectionDurationStats.getMax(); + } + + @ManagedAttribute("Connection duration mean in ms") + public double getConnectionDurationMean() + { + return _connectionDurationStats.getMean(); + } + + @ManagedAttribute("Connection duration standard deviation") + public double getConnectionDurationStdDev() + { + return _connectionDurationStats.getStdDev(); + } + + @ManagedAttribute("Messages In for all connections") + public int getMessagesIn() + { + return (int)_messagesIn.getTotal(); + } + + @ManagedAttribute("Messages In per connection maximum") + public int getMessagesInPerConnectionMax() + { + return (int)_messagesIn.getMax(); + } + + @ManagedAttribute("Messages In per connection mean") + public double getMessagesInPerConnectionMean() + { + return _messagesIn.getMean(); + } + + @ManagedAttribute("Messages In per connection standard deviation") + public double getMessagesInPerConnectionStdDev() + { + return _messagesIn.getStdDev(); + } + + @ManagedAttribute("Connections open") + public int getConnectionsOpen() + { + return (int)_connectionStats.getCurrent(); + } + + @ManagedAttribute("Connections open maximum") + public int getConnectionsOpenMax() + { + return (int)_connectionStats.getMax(); + } + + @ManagedAttribute("Messages Out for all connections") + public int getMessagesOut() + { + return (int)_messagesIn.getTotal(); + } + + @ManagedAttribute("Messages In per connection maximum") + public int getMessagesOutPerConnectionMax() + { + return (int)_messagesIn.getMax(); + } + + @ManagedAttribute("Messages In per connection mean") + public double getMessagesOutPerConnectionMean() + { + return _messagesIn.getMean(); + } + + @ManagedAttribute("Messages In per connection standard deviation") + public double getMessagesOutPerConnectionStdDev() + { + return _messagesIn.getStdDev(); + } + + @ManagedAttribute("Connection statistics started ms since epoch") + public long getStartedMillis() + { + long start = _startMillis.get(); + return start < 0 ? 0 : System.currentTimeMillis() - start; + } + + @ManagedAttribute("Messages in per second calculated over period since last called") + public int getMessagesInPerSecond() + { + update(); + return _messagesInPerSecond; + } + + @ManagedAttribute("Messages out per second calculated over period since last called") + public int getMessagesOutPerSecond() + { + update(); + return _messagesOutPerSecond; + } + + @Override + public void doStart() + { + reset(); + } + + @Override + public void doStop() + { + _samples.clear(); + } + + @ManagedOperation("Reset the statistics") + public void reset() + { + _startMillis.set(System.currentTimeMillis()); + _messagesIn.reset(); + _messagesOut.reset(); + _connectionStats.reset(); + _connectionDurationStats.reset(); + _samples.clear(); + } + + @Override + @ManagedOperation("dump thread state") + public String dump() + { + return ContainerLifeCycle.dump(this); + } + + @Override + public void dump(Appendable out, String indent) throws IOException + { + ContainerLifeCycle.dumpObject(out,this); + ContainerLifeCycle.dump(out,indent,Arrays.asList(new String[]{"connections="+_connectionStats,"duration="+_connectionDurationStats,"in="+_messagesIn,"out="+_messagesOut})); + } + + public static void addToAllConnectors(Server server) + { + for (Connector connector : server.getConnectors()) + { + if (connector instanceof Container) + ((Container)connector).addBean(new ConnectorStatistics()); + } + } + + private static final long SECOND_NANOS=TimeUnit.SECONDS.toNanos(1); + private synchronized void update() + { + long now=System.nanoTime(); + long then=_nanoStamp.get(); + long duration=now-then; + + if (duration>SECOND_NANOS/2) + { + if (_nanoStamp.compareAndSet(then,now)) + { + long msgsIn=_closedIn.getAndSet(0); + long msgsOut=_closedOut.getAndSet(0); + + for (Map.Entry entry : _samples.entrySet()) + { + Connection connection=entry.getKey(); + Sample sample = entry.getValue(); + Sample next = new Sample(connection); + if (_samples.replace(connection,sample,next)) + { + msgsIn+=next._messagesIn-sample._messagesIn; + msgsOut+=next._messagesOut-sample._messagesOut; + } + } + + _messagesInPerSecond=(int)(msgsIn*SECOND_NANOS/duration); + _messagesOutPerSecond=(int)(msgsOut*SECOND_NANOS/duration); + } + } + } + + private static class Sample + { + Sample() + { + _messagesIn=0; + _messagesOut=0; + } + + Sample(Connection connection) + { + _messagesIn=connection.getMessagesIn(); + _messagesOut=connection.getMessagesOut(); + } + + final int _messagesIn; + final int _messagesOut; + } +}