package org.mortbay.jetty.handler; import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.mortbay.jetty.HttpConnection; import org.mortbay.jetty.Response; /** * @version $Revision$ $Date: 2009-06-17 07:36:08 +1000 (Wed, 17 Jun 2009) $ */ public class AtomicStatisticsHandler extends AbstractStatisticsHandler { private transient final AtomicLong _statsStartedAt = new AtomicLong(); private transient final AtomicInteger _requests = new AtomicInteger(); private transient final AtomicLong _minRequestTime = new AtomicLong(); private transient final AtomicLong _maxRequestTime = new AtomicLong(); private transient final AtomicLong _totalRequestTime = new AtomicLong(); private transient final AtomicInteger _requestsActive = new AtomicInteger(); private transient final AtomicInteger _requestsActiveMax = new AtomicInteger(); private transient final AtomicInteger _responses1xx = new AtomicInteger(); private transient final AtomicInteger _responses2xx = new AtomicInteger(); private transient final AtomicInteger _responses3xx = new AtomicInteger(); private transient final AtomicInteger _responses4xx = new AtomicInteger(); private transient final AtomicInteger _responses5xx = new AtomicInteger(); public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException { _requests.incrementAndGet(); int actives = _requestsActive.incrementAndGet(); // Update the max value, using a non-blocking algorithm int oldMaxActives = _requestsActiveMax.get(); while (actives > oldMaxActives) { if (_requestsActiveMax.compareAndSet(oldMaxActives, actives)) break; oldMaxActives = _requestsActiveMax.get(); } long requestStartTime = System.currentTimeMillis(); try { super.handle(target, request, response, dispatch); } finally { long requestTime = System.currentTimeMillis() - requestStartTime; // Set to 0 if the value is negative, using a non-blocking algorithm actives = _requestsActive.decrementAndGet(); while (actives < 0) { if (_requestsActive.compareAndSet(actives, 0)) break; actives = _requestsActive.get(); } // Update the times, using a non-blocking algorithm long oldMinTime = _minRequestTime.get(); while (requestTime < oldMinTime) { if (_minRequestTime.compareAndSet(oldMinTime, requestTime)) break; oldMinTime = _minRequestTime.get(); } long oldMaxTime = _maxRequestTime.get(); while (requestTime > oldMaxTime) { if (_maxRequestTime.compareAndSet(oldMaxTime, requestTime)) break; oldMaxTime = _maxRequestTime.get(); } _totalRequestTime.addAndGet(requestTime); Response jettyResponse = (response instanceof Response) ? (Response) response : HttpConnection.getCurrentConnection().getResponse(); switch (jettyResponse.getStatus() / 100) { case 1: _responses1xx.incrementAndGet(); break; case 2: _responses2xx.incrementAndGet(); break; case 3: _responses3xx.incrementAndGet(); break; case 4: _responses4xx.incrementAndGet(); break; case 5: _responses5xx.incrementAndGet(); break; default: break; } } } public void statsReset() { _statsStartedAt.set(System.currentTimeMillis()); _requests.set(0); _minRequestTime.set(Long.MAX_VALUE); _maxRequestTime.set(0L); _totalRequestTime.set(0L); _requestsActive.set(0); _requestsActiveMax.set(0); _responses1xx.set(0); _responses2xx.set(0); _responses3xx.set(0); _responses4xx.set(0); _responses5xx.set(0); } public int getRequests() { return _requests.get(); } public int getRequestsActive() { return _requestsActive.get(); } public int getRequestsActiveMax() { return _requestsActiveMax.get(); } public int getResponses1xx() { return _responses1xx.get(); } public int getResponses2xx() { return _responses2xx.get(); } public int getResponses3xx() { return _responses3xx.get(); } public int getResponses4xx() { return _responses4xx.get(); } public int getResponses5xx() { return _responses5xx.get(); } public long getStatsOnMs() { return System.currentTimeMillis() - _statsStartedAt.get(); } public long getRequestTimeMin() { return _minRequestTime.get(); } public long getRequestTimeMax() { return _maxRequestTime.get(); } public long getRequestTimeTotal() { return _totalRequestTime.get(); } public long getRequestTimeAverage() { int requests = getRequests(); return requests == 0 ? 0 : getRequestTimeTotal() / requests; } }