Index: src/main/java/org/glassfish/web/admin/monitor/HttpServiceStatsProvider.java =================================================================== --- src/main/java/org/glassfish/web/admin/monitor/HttpServiceStatsProvider.java (revision 32036) +++ src/main/java/org/glassfish/web/admin/monitor/HttpServiceStatsProvider.java (working copy) @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development @@ -35,15 +35,13 @@ */ package org.glassfish.web.admin.monitor; -import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; import org.glassfish.external.statistics.CountStatistic; -import org.glassfish.external.statistics.TimeStatistic; +import org.glassfish.external.statistics.annotations.Reset; import org.glassfish.external.statistics.impl.CountStatisticImpl; +import org.glassfish.external.statistics.impl.StatisticImpl; import org.glassfish.external.statistics.impl.TimeStatisticImpl; -import org.glassfish.flashlight.statistics.*; -import org.glassfish.flashlight.statistics.factory.TimeStatsFactory; import org.glassfish.external.probe.provider.annotations.*; import org.glassfish.gmbal.Description; import org.glassfish.gmbal.AMXMetadata; @@ -70,7 +68,18 @@ //private Counter requestCount = CounterFactory.createCount(); //Provides the cumulative value of the error count. The error count represents //the number of cases where the response code was greater than or equal to 400. - private CountStatisticImpl errorCount = new CountStatisticImpl("ErrorCount", "count", "Cumulative value of the error count, with error count representing the number of cases where the response code was greater than or equal to 400"); + private CountStatisticImpl errorCount = new CountStatisticImpl("ErrorCount", + StatisticImpl.UNIT_COUNT, + "Cumulative value of the error count, with error count representing the number of cases where the response code was greater than or equal to 400"); + private CountStatisticImpl maxTime = new CountStatisticImpl("MaxTime", + StatisticImpl.UNIT_MILLISECOND, + "Longest response time for a request; not a cumulative value, but the largest response time from among the response times"); + private CountStatisticImpl processingTime = new CountStatisticImpl("ProcessingTime", + StatisticImpl.UNIT_MILLISECOND, + "Cumulative value of the times taken to process each request, with processing time being the average of request processing times over the request count"); + private CountStatisticImpl requestCount = new CountStatisticImpl("RequestCount", + StatisticImpl.UNIT_COUNT, + "Cumulative number of requests processed so far"); private CountStatisticImpl count200 = new CountStatisticImpl("Count200", "count", "Number of responses with a status code equal to 200"); private CountStatisticImpl count2xx = new CountStatisticImpl("Count2xx", "count", "Number of responses with a status code in the 2xx range"); private CountStatisticImpl count302 = new CountStatisticImpl("Count302", "count", "Number of responses with a status code equal to 302"); @@ -84,10 +93,27 @@ private CountStatisticImpl count503 = new CountStatisticImpl("Count503", "count", "Number of responses with a status code equal to 503"); private CountStatisticImpl count5xx = new CountStatisticImpl("Count5xx", "count", "Number of responses with a status code in the 5xx range"); private CountStatisticImpl countOther = new CountStatisticImpl("CountOther", "count", "Number of responses with a status code outside the 2xx, 3xx, 4xx, and 5xx range"); - private TimeStats requestProcessTime = TimeStatsFactory.createTimeStatsMilli(); + private TimeStatisticImpl requestProcessTime = new TimeStatisticImpl(0L, 0L, 0L, 0L, + "", "", "", System.currentTimeMillis(), -1L); private Logger logger = Logger.getLogger(HttpServiceStatsProvider.class.getName()); private String virtualServerName = null; + private ThreadLocal individualData = new ThreadLocal (){ + + TimeStatData tsd; + + protected TimeStatData initialValue (){ + tsd = new TimeStatData (); + return tsd; + } + public TimeStatData get (){ + if (tsd == null) + tsd = new TimeStatData(); + return tsd; + } + + }; + public HttpServiceStatsProvider(String vsName) { this.virtualServerName = vsName; } @@ -98,51 +124,29 @@ @ManagedAttribute(id="maxtime") @Description( "Provides the longest response time for a response - not a cumulative value, but the largest response time from among response times." ) - public TimeStatistic getMaximumTime() { - TimeStatisticImpl maxTime = new TimeStatisticImpl( - requestProcessTime.getMaximumTime(), - requestProcessTime.getMaximumTime(), - requestProcessTime.getMinimumTime(), - requestProcessTime.getTotalTime(), - "MaxTime", - "milliseconds", - "Provides the longest response time for a response - not a cumulative value, but the largest response time from among response times.", - requestProcessTime.getStartTime(), - requestProcessTime.getLastSampleTime()); + public CountStatistic getMaxTime() { + maxTime.setCount(requestProcessTime.getMaxTime()); return maxTime; } @ManagedAttribute(id="requestcount") @Description( "Provides cumulative number of requests processed so far" ) public CountStatistic getCount() { - CountStatisticImpl requestCount = new CountStatisticImpl( - "RequestCount", - "count", - "Provides cumulative number of requests processed so far."); requestCount.setCount(requestProcessTime.getCount()); return requestCount; } @ManagedAttribute(id="processingtime") @Description( "Provides cumulative value of the times taken to process each request The processing time is the average request processing times over the request count." ) - public TimeStatistic getTime() { - TimeStatisticImpl processingTime = new TimeStatisticImpl( - (long) requestProcessTime.getTime(), - requestProcessTime.getMaximumTime(), - requestProcessTime.getMinimumTime(), - requestProcessTime.getTotalTime(), - "ProcessingTime", - "milliseconds", - "Provides cumulative value of the times taken to process each request The processing time is the average request processing times over the request count.", - requestProcessTime.getStartTime(), - requestProcessTime.getLastSampleTime()); + public CountStatistic getTime() { + processingTime.setCount(this.getProcessTime()); return processingTime; } @ManagedAttribute(id="errorcount") @Description( "" ) public CountStatistic getErrorCount() { - return errorCount.getStatistic(); + return errorCount; } @ManagedAttribute(id="count200") @@ -231,7 +235,7 @@ @ProbeParam("contextPath") String contextPath, @ProbeParam("servletPath") String servletPath) { if ((hostName != null) && (hostName.equals(virtualServerName))) { - requestProcessTime.entry(); + individualData.get().setEntryTime(System.currentTimeMillis()); if (logger.isLoggable(Level.FINEST)) { logger.finest( "[TM]requestStartEvent received - virtual-server = " + @@ -249,7 +253,9 @@ @ProbeParam("servletPath") String servletPath, @ProbeParam("statusCode") int statusCode) { if ((hostName != null) && (hostName.equals(virtualServerName))) { - requestProcessTime.exit(); + TimeStatData tsd = individualData.get(); + tsd.setExitTime(System.currentTimeMillis()); + requestProcessTime.incrementCount(tsd.getTotalTime()); incrementStatsCounter(statusCode); if (logger.isLoggable(Level.FINEST)) { logger.finest( @@ -258,14 +264,19 @@ contextPath + " : servlet = " + servletPath + " :Response code = " + statusCode + " :Response time = " + - requestProcessTime.getTime()); + tsd.getTotalTime()); } } } public long getProcessTime() { - return requestProcessTime.getTotalTime()/requestProcessTime.getCount(); + long count = requestProcessTime.getCount(); + long processTime = -1L; + if (count != 0) { + processTime = requestProcessTime.getTotalTime()/count; + } + return processTime; } private void incrementStatsCounter(int statusCode) { @@ -313,4 +324,68 @@ if (statusCode >= 400) errorCount.increment(); } + + //Need to add this because requestProcessTime needs to be reset. + //Since it is not exposed as public statistic the reset() would not get + //called on its TimeStatisticImpl object so we need to use @Reset instead. + //If @Reset is used then reset() won't be called on the statistic impl objects + //so all the stats need to reset here as well. + @Reset + public void reset() { + this.requestProcessTime.reset(); + this.count200.reset(); + this.count2xx.reset(); + this.count302.reset(); + this.count304.reset(); + this.count3xx.reset(); + this.count400.reset(); + this.count401.reset(); + this.count403.reset(); + this.count404.reset(); + this.count4xx.reset(); + this.count503.reset(); + this.count5xx.reset(); + this.countOther.reset(); + this.errorCount.reset(); + this.maxTime.reset(); + this.processingTime.reset(); + this.requestCount.reset(); + } + + private class TimeStatData { + private long entryTime = 0; + private long exitTime = 0; + private long totalTime = 0; + + + public long getEntryTime() { + return entryTime; + } + + public void setEntryTime(long entryTime) { + this.entryTime = entryTime; + } + + public long getExitTime() { + return exitTime; + } + + public void setExitTime(long exitTime) { + this.exitTime = exitTime; + } + + public long getTotalTime() { + totalTime = exitTime - entryTime; + return totalTime; + } + + public void setTotalTime(long totalTime) { + this.totalTime = totalTime; + } + public void setReset (){ + entryTime = 0; + exitTime = 0; + totalTime = 0; + } + } }