Author: justin
Date: Fri Feb 17 02:37:59 2012
New Revision: 1245300
URL: http://svn.apache.org/viewvc?rev=1245300&view=rev
Log:
SLING-2412 - adding peak recursion depth and servlet call count stats
Modified:
sling/trunk/bundles/engine/pom.xml
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/RequestProcessorMBeanImpl.java
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/jmx/RequestProcessorMBean.java
sling/trunk/bundles/engine/src/test/java/org/apache/sling/engine/impl/RequestProcessorMBeanImplTest.java
Modified: sling/trunk/bundles/engine/pom.xml
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/pom.xml?rev=1245300&r1=1245299&r2=1245300&view=diff
==============================================================================
--- sling/trunk/bundles/engine/pom.xml (original)
+++ sling/trunk/bundles/engine/pom.xml Fri Feb 17 02:37:59 2012
@@ -181,6 +181,24 @@
<version>2.2</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.jmock</groupId>
+ <artifactId>jmock-legacy</artifactId>
+ <version>2.5.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>cglib</groupId>
+ <artifactId>cglib-nodep</artifactId>
+ <version>2.1_3</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.objenesis</groupId>
+ <artifactId>objenesis</artifactId>
+ <version>1.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
<profile>
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/RequestProcessorMBeanImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/RequestProcessorMBeanImpl.java?rev=1245300&r1=1245299&r2=1245300&view=diff
==============================================================================
---
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/RequestProcessorMBeanImpl.java
(original)
+++
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/RequestProcessorMBeanImpl.java
Fri Feb 17 02:37:59 2012
@@ -19,6 +19,7 @@ package org.apache.sling.engine.impl;
import javax.management.NotCompliantMBeanException;
import javax.management.StandardMBean;
+import org.apache.sling.engine.impl.request.RequestData;
import org.apache.sling.engine.jmx.RequestProcessorMBean;
/**
@@ -42,13 +43,33 @@ class RequestProcessorMBeanImpl extends
// sum of squared request durations
private volatile double durationMsecSumX2;
+ private volatile int servletCallCountMin;
+
+ private volatile int servletCallCountMax;
+
+ private volatile double servletCallCountSumX;
+
+ private volatile double servletCallCountSumX2;
+
+ private volatile int peakRecursionDepthMin;
+
+ private volatile int peakRecursionDepthMax;
+
+ private volatile double peakRecursionDepthSumX;
+
+ private volatile double peakRecursionDepthSumX2;
+
RequestProcessorMBeanImpl() throws NotCompliantMBeanException {
super(RequestProcessorMBean.class);
resetStatistics();
}
- synchronized void addRequestData(final long duration) {
+ synchronized void addRequestData(final RequestData data) {
this.n++;
+
+ final long duration = data.getElapsedTimeMsec();
+ final int servletCallCount = data.getServletCallCount();
+ final int peakRecursionDepth = data.getPeakRecusionDepth();
if (duration < this.durationMsecMin) {
this.durationMsecMin = duration;
@@ -59,6 +80,24 @@ class RequestProcessorMBeanImpl extends
this.durationMsecSumX += duration;
this.durationMsecSumX2 += (duration * duration);
+
+ if (servletCallCount < this.servletCallCountMin) {
+ this.servletCallCountMin = servletCallCount;
+ }
+ if (servletCallCount > this.servletCallCountMax) {
+ this.servletCallCountMax = servletCallCount;
+ }
+ this.servletCallCountSumX += servletCallCount;
+ this.servletCallCountSumX2 += (servletCallCount * servletCallCount);
+
+ if (peakRecursionDepth < this.peakRecursionDepthMin) {
+ this.peakRecursionDepthMin = peakRecursionDepth;
+ }
+ if (peakRecursionDepth > this.peakRecursionDepthMax) {
+ this.peakRecursionDepthMax = peakRecursionDepth;
+ }
+ this.peakRecursionDepthSumX += peakRecursionDepth;
+ this.peakRecursionDepthSumX2 += (peakRecursionDepth *
peakRecursionDepth);
}
public long getRequestsCount() {
@@ -96,7 +135,63 @@ class RequestProcessorMBeanImpl extends
public synchronized void resetStatistics() {
this.durationMsecMin = Long.MAX_VALUE;
this.durationMsecMax = 0;
+ this.servletCallCountMin = Integer.MAX_VALUE;
+ this.servletCallCountMax = 0;
+ this.peakRecursionDepthMin = Integer.MAX_VALUE;
+ this.peakRecursionDepthMax = 0;
+
this.n = 0;
+
+ }
+
+ public int getMaxPeakRecursionDepth() {
+ return peakRecursionDepthMax;
+ }
+
+ public int getMinPeakRecursionDepth() {
+ return peakRecursionDepthMin;
+ }
+
+ public double getMeanPeakRecursionDepth() {
+ if (this.n > 0) {
+ return this.peakRecursionDepthSumX / this.n;
+ } else {
+ return 0;
+ }
+ }
+
+ public double getStandardDeviationPeakRecursionDepth() {
+ if (this.n > 1) {
+ return Math.sqrt((this.peakRecursionDepthSumX2 -
this.peakRecursionDepthSumX * this.peakRecursionDepthSumX / this.n) / (this.n -
1));
+ }
+
+ // single data point has no deviation
+ return 0;
+ }
+
+ public int getMaxServletCallCount() {
+ return this.servletCallCountMax;
+ }
+
+ public int getMinServletCallCount() {
+ return this.servletCallCountMin;
+ }
+
+ public double getMeanServletCallCount() {
+ if (this.n > 0) {
+ return this.servletCallCountSumX / this.n;
+ } else {
+ return 0;
+ }
+ }
+
+ public double getStandardDeviationServletCallCount() {
+ if (this.n > 1) {
+ return Math.sqrt((this.servletCallCountSumX2 -
this.servletCallCountSumX * this.servletCallCountSumX / this.n) / (this.n - 1));
+ }
+
+ // single data point has no deviation
+ return 0;
}
}
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java?rev=1245300&r1=1245299&r2=1245300&view=diff
==============================================================================
---
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
(original)
+++
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
Fri Feb 17 02:37:59 2012
@@ -126,8 +126,6 @@ public class SlingRequestProcessorImpl i
// record the request for the web console display
RequestHistoryConsolePlugin.recordRequest(request);
- long startTimestamp = System.currentTimeMillis();
-
try {
final ServletResolver sr = this.servletResolver;
@@ -223,9 +221,8 @@ public class SlingRequestProcessorImpl i
handleError(t, request, response);
} finally {
- long elapsed = System.currentTimeMillis() - startTimestamp;
if (mbean != null) {
- mbean.addRequestData(elapsed);
+ mbean.addRequestData(requestData);
}
}
}
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java?rev=1245300&r1=1245299&r2=1245300&view=diff
==============================================================================
---
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
(original)
+++
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/impl/request/RequestData.java
Fri Feb 17 02:37:59 2012
@@ -108,6 +108,8 @@ public class RequestData {
/** The SlingMainServlet used for request dispatching and other stuff */
private final SlingRequestProcessorImpl slingRequestProcessor;
+
+ private final long startTimestamp;
/** The original servlet Servlet Request Object */
private HttpServletRequest servletRequest;
@@ -150,6 +152,11 @@ public class RequestData {
*/
private int recursionDepth;
+ /**
+ * The peak value for the recursion depth.
+ */
+ private int peakRecusionDepth;
+
public static void setMaxCallCounter(int maxCallCounter) {
RequestData.maxCallCounter = maxCallCounter;
}
@@ -172,7 +179,8 @@ public class RequestData {
public RequestData(SlingRequestProcessorImpl slingRequestProcessor,
HttpServletRequest request, HttpServletResponse response) {
-
+ this.startTimestamp = System.currentTimeMillis();
+
this.slingRequestProcessor = slingRequestProcessor;
this.servletRequest = request;
@@ -519,6 +527,9 @@ public class RequestData {
throw new
RecursionTooDeepException(requestPathInfo.getResourcePath());
}
this.recursionDepth++;
+ if (this.recursionDepth > this.peakRecusionDepth) {
+ this.peakRecusionDepth = this.recursionDepth;
+ }
currentContentData = new ContentData(resource, requestPathInfo);
return currentContentData;
}
@@ -539,6 +550,18 @@ public class RequestData {
public RequestProgressTracker getRequestProgressTracker() {
return requestProgressTracker;
}
+
+ public int getPeakRecusionDepth() {
+ return peakRecusionDepth;
+ }
+
+ public int getServletCallCount() {
+ return servletCallCounter;
+ }
+
+ public long getElapsedTimeMsec() {
+ return System.currentTimeMillis() - startTimestamp;
+ }
/**
* Sets the name of the currently active servlet and returns the name of
the
Modified:
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/jmx/RequestProcessorMBean.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/jmx/RequestProcessorMBean.java?rev=1245300&r1=1245299&r2=1245300&view=diff
==============================================================================
---
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/jmx/RequestProcessorMBean.java
(original)
+++
sling/trunk/bundles/engine/src/main/java/org/apache/sling/engine/jmx/RequestProcessorMBean.java
Fri Feb 17 02:37:59 2012
@@ -63,6 +63,74 @@ public interface RequestProcessorMBean {
double getStandardDeviationDurationMsec();
/**
+ * Returns the maximum peak recursive execution depth since last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ int getMaxPeakRecursionDepth();
+
+
+ /**
+ * Returns the minimal peak recursive execution depth since last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ int getMinPeakRecursionDepth();
+
+
+ /**
+ * Returns the mean peak recursive execution depth since last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ double getMeanPeakRecursionDepth();
+
+
+ /**
+ * Returns the standard deviation of peak recursive execution depth since
last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ double getStandardDeviationPeakRecursionDepth();
+
+ /**
+ * Returns the maximum servlet call count since last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ int getMaxServletCallCount();
+
+
+ /**
+ * Returns the minimum servlet call count since last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ int getMinServletCallCount();
+
+ /**
+ * Returns the mean servlet call count since last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ double getMeanServletCallCount();
+
+ /**
+ * Returns the standard deviation servlet call counts since last
+ * resetting the statistics.
+ *
+ * @see #resetStatistics()
+ */
+ double getStandardDeviationServletCallCount();
+
+ /**
* Resets all statistics values and restarts from zero.
*/
void resetStatistics();
Modified:
sling/trunk/bundles/engine/src/test/java/org/apache/sling/engine/impl/RequestProcessorMBeanImplTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/bundles/engine/src/test/java/org/apache/sling/engine/impl/RequestProcessorMBeanImplTest.java?rev=1245300&r1=1245299&r2=1245300&view=diff
==============================================================================
---
sling/trunk/bundles/engine/src/test/java/org/apache/sling/engine/impl/RequestProcessorMBeanImplTest.java
(original)
+++
sling/trunk/bundles/engine/src/test/java/org/apache/sling/engine/impl/RequestProcessorMBeanImplTest.java
Fri Feb 17 02:37:59 2012
@@ -18,15 +18,28 @@
*/
package org.apache.sling.engine.impl;
+import static org.junit.Assert.*;
+
import java.util.Random;
import javax.management.NotCompliantMBeanException;
-import junit.framework.TestCase;
-
import org.apache.commons.math.stat.descriptive.SummaryStatistics;
-
-public class RequestProcessorMBeanImplTest extends TestCase {
+import org.apache.sling.engine.impl.request.RequestData;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.jmock.lib.legacy.ClassImposteriser;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(JMock.class)
+public class RequestProcessorMBeanImplTest {
+
+ private Mockery context = new JUnit4Mockery() {{
+ setImposteriser(ClassImposteriser.INSTANCE);
+ }};
/**
* Asserts that the simple standard deviation algorithm used by the
@@ -35,38 +48,82 @@ public class RequestProcessorMBeanImplTe
*
* @throws NotCompliantMBeanException not expected
*/
+ @Test
public void test_statistics() throws NotCompliantMBeanException {
- final SummaryStatistics mathStats = new SummaryStatistics();
+ final SummaryStatistics durationStats = new SummaryStatistics();
+ final SummaryStatistics servletCallCountStats = new
SummaryStatistics();
+ final SummaryStatistics peakRecursionDepthStats = new
SummaryStatistics();
final RequestProcessorMBeanImpl bean = new RequestProcessorMBeanImpl();
assertEquals(0l, bean.getRequestsCount());
assertEquals(Long.MAX_VALUE, bean.getMinRequestDurationMsec());
assertEquals(0l, bean.getMaxRequestDurationMsec());
- assertEquals(0.0, bean.getMeanRequestDurationMsec());
- assertEquals(0.0, bean.getStandardDeviationDurationMsec());
+ assertEquals(0.0, bean.getMeanRequestDurationMsec(), 0);
+ assertEquals(0.0, bean.getStandardDeviationDurationMsec(), 0);
+
+ assertEquals(Integer.MAX_VALUE, bean.getMinServletCallCount());
+ assertEquals(0l, bean.getMaxServletCallCount());
+ assertEquals(0.0, bean.getMeanServletCallCount(), 0);
+ assertEquals(0.0, bean.getStandardDeviationServletCallCount(), 0);
+
+ assertEquals(Integer.MAX_VALUE, bean.getMinPeakRecursionDepth());
+ assertEquals(0l, bean.getMaxPeakRecursionDepth());
+ assertEquals(0.0, bean.getMeanPeakRecursionDepth(), 0);
+ assertEquals(0.0, bean.getStandardDeviationPeakRecursionDepth(), 0);
final Random random = new Random(System.currentTimeMillis() / 17);
final int num = 10000;
final int min = 85;
final int max = 250;
for (int i = 0; i < num; i++) {
- final long value = min + random.nextInt(max - min);
- mathStats.addValue(value);
- bean.addRequestData(value);
+ final long durationValue = min + random.nextInt(max - min);
+ final int callCountValue = min + random.nextInt(max - min);
+ final int peakRecursionDepthValue = min + random.nextInt(max -
min);
+ durationStats.addValue(durationValue);
+ servletCallCountStats.addValue(callCountValue);
+ peakRecursionDepthStats.addValue(peakRecursionDepthValue);
+
+ final RequestData requestData = context.mock(RequestData.class,
"requestData" + i);
+ context.checking(new Expectations() {{
+ one(requestData).getElapsedTimeMsec();
+ will(returnValue(durationValue));
+
+ one(requestData).getServletCallCount();
+ will(returnValue(callCountValue));
+
+ one(requestData).getPeakRecusionDepth();
+ will(returnValue(peakRecursionDepthValue));
+ }});
+
+
+ bean.addRequestData(requestData);
}
- TestCase.assertEquals("Number of points must be the same",
mathStats.getN(), bean.getRequestsCount());
- TestCase.assertEquals("Min must be equal", (long) mathStats.getMin(),
bean.getMinRequestDurationMsec());
- TestCase.assertEquals("Max must be equal", (long) mathStats.getMax(),
bean.getMaxRequestDurationMsec());
- assertAlmostEqual("Mean", mathStats.getMean(),
bean.getMeanRequestDurationMsec(), num);
- assertAlmostEqual("Standard Deviation",
mathStats.getStandardDeviation(),
+ assertEquals("Number of points must be the same",
durationStats.getN(), bean.getRequestsCount());
+
+ assertEquals("Min Duration must be equal", (long)
durationStats.getMin(), bean.getMinRequestDurationMsec());
+ assertEquals("Max Duration must be equal", (long)
durationStats.getMax(), bean.getMaxRequestDurationMsec());
+ assertAlmostEqual("Mean Duration", durationStats.getMean(),
bean.getMeanRequestDurationMsec(), num);
+ assertAlmostEqual("Standard Deviation Duration",
durationStats.getStandardDeviation(),
bean.getStandardDeviationDurationMsec(), num);
+
+ assertEquals("Min Servlet Call Count must be equal", (long)
servletCallCountStats.getMin(), bean.getMinServletCallCount());
+ assertEquals("Max Servlet Call Count must be equal", (long)
servletCallCountStats.getMax(), bean.getMaxServletCallCount());
+ assertAlmostEqual("Mean Servlet Call Count",
servletCallCountStats.getMean(), bean.getMeanServletCallCount(), num);
+ assertAlmostEqual("Standard Deviation Servlet Call Count",
servletCallCountStats.getStandardDeviation(),
+ bean.getStandardDeviationServletCallCount(), num);
+
+ assertEquals("Min Peak Recursion Depth must be equal", (long)
peakRecursionDepthStats.getMin(), bean.getMinPeakRecursionDepth());
+ assertEquals("Max Peak Recursion Depth must be equal", (long)
peakRecursionDepthStats.getMax(), bean.getMaxPeakRecursionDepth());
+ assertAlmostEqual("Mean Peak Recursion Depth",
peakRecursionDepthStats.getMean(), bean.getMeanPeakRecursionDepth(), num);
+ assertAlmostEqual("Standard Deviation Peak Recursion Depth",
peakRecursionDepthStats.getStandardDeviation(),
+ bean.getStandardDeviationPeakRecursionDepth(), num);
}
private void assertAlmostEqual(final String message, final double v1,
final double v2, int samples) {
final double centi = v1 / samples;
if (v2 < (v1 - centi) || v2 > (v1 + centi)) {
- TestCase.fail(message + " (expected: " + v2 + " in (" + (v1 -
centi) + "," + (v1 + centi) + "))");
+ fail(message + " (expected: " + v2 + " in (" + (v1 - centi) + ","
+ (v1 + centi) + "))");
}
}
}