484818 - Expose interesting HTTP/2 attributes and operations via JMX.

Added flow control stall times and improved dump().
This commit is contained in:
Simone Bordet 2015-12-28 14:30:24 +01:00
parent 460e6e2ff3
commit bf757aafa9
3 changed files with 52 additions and 9 deletions

View File

@ -18,6 +18,10 @@
package org.eclipse.jetty.http2;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.eclipse.jetty.http2.api.Stream;
@ -25,15 +29,20 @@ import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
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.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ManagedObject
public abstract class AbstractFlowControlStrategy implements FlowControlStrategy
public abstract class AbstractFlowControlStrategy implements FlowControlStrategy, Dumpable
{
protected static final Logger LOG = Log.getLogger(FlowControlStrategy.class);
private final AtomicLong sessionStalls = new AtomicLong();
private final AtomicLong sessionStall = new AtomicLong();
private final AtomicLong sessionStallTime = new AtomicLong();
private final Map<IStream, Long> streamsStalls = new ConcurrentHashMap<>();
private final AtomicLong streamsStallTime = new AtomicLong();
private int initialStreamSendWindow;
private int initialStreamRecvWindow;
@ -174,38 +183,62 @@ public abstract class AbstractFlowControlStrategy implements FlowControlStrategy
protected void onSessionStalled(ISession session)
{
sessionStall.set(System.nanoTime());
if (LOG.isDebugEnabled())
LOG.debug("Session stalled {}", session);
sessionStalls.incrementAndGet();
}
protected void onStreamStalled(IStream stream)
{
streamsStalls.put(stream, System.nanoTime());
if (LOG.isDebugEnabled())
LOG.debug("Stream stalled {}", stream);
}
protected void onSessionUnstalled(ISession session)
{
sessionStallTime.addAndGet(System.nanoTime() - sessionStall.getAndSet(0));
if (LOG.isDebugEnabled())
LOG.debug("Session unstalled {}", session);
}
protected void onStreamUnstalled(IStream stream)
{
Long time = streamsStalls.remove(stream);
if (time != null)
streamsStallTime.addAndGet(System.nanoTime() - time);
if (LOG.isDebugEnabled())
LOG.debug("Stream unstalled {}", stream);
}
@ManagedAttribute(value = "The number of times the session flow control has stalled", readonly = true)
public long getSessionStallCount()
@ManagedAttribute(value = "The time, in milliseconds, that the session flow control has stalled", readonly = true)
public long getSessionStallTime()
{
return sessionStalls.get();
return TimeUnit.NANOSECONDS.toMillis(sessionStallTime.get());
}
@ManagedAttribute(value = "The time, in milliseconds, that the streams flow control has stalled", readonly = true)
public long getStreamsStallTime()
{
return TimeUnit.NANOSECONDS.toMillis(streamsStallTime.get());
}
@ManagedOperation(value = "Resets the statistics", impact = "ACTION")
public void reset()
{
sessionStalls.set(0);
sessionStallTime.set(0);
streamsStallTime.set(0);
}
@Override
public String dump()
{
return ContainerLifeCycle.dump(this);
}
@Override
public void dump(Appendable out, String indent) throws IOException
{
out.append(toString()).append(System.lineSeparator());
}
}

View File

@ -198,4 +198,15 @@ public class BufferingFlowControlStrategy extends AbstractFlowControlStrategy
Atomics.updateMax(maxSessionRecvWindow, sessionWindow);
}
}
@Override
public String toString()
{
return String.format("%s@%x[ratio=%.2f,sessionStallTime=%dms,streamsStallTime=%dms]",
getClass().getSimpleName(),
hashCode(),
bufferRatio,
getSessionStallTime(),
getStreamsStallTime());
}
}

View File

@ -34,7 +34,6 @@ import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
@ManagedObject
@ -148,7 +147,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
return new ServerParser(connector.getByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize());
}
private static class ConnectionListener extends ContainerLifeCycle implements Connection.Listener
private class ConnectionListener implements Connection.Listener
{
@Override
public void onOpened(Connection connection)