You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by ts...@apache.org on 2016/03/24 21:28:34 UTC

wicket git commit: WICKET-6128 and WICKET-6127 - Session and Request measurement

Repository: wicket
Updated Branches:
  refs/heads/master ab784c011 -> 50b6cadc5


WICKET-6128 and WICKET-6127 - Session and Request measurement

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/50b6cadc
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/50b6cadc
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/50b6cadc

Branch: refs/heads/master
Commit: 50b6cadc5d44a45c261f599501cac20b5c20c766
Parents: ab784c0
Author: Tobias Soloschenko <ts...@apache.org>
Authored: Thu Mar 24 21:26:43 2016 +0100
Committer: Tobias Soloschenko <ts...@apache.org>
Committed: Thu Mar 24 21:26:43 2016 +0100

----------------------------------------------------------------------
 wicket-experimental/wicket-metrics/pom.xml      |   4 +
 .../apache/wicket/metrics/WicketMetrics.java    | 217 +++++++++++++++++--
 .../wicket/metrics/WicketMetricsSettings.java   |   8 +-
 .../aspects/WicketFilterRequestCycleAspect.java |   3 +-
 .../WicketFilterRequestCycleUrlAspect.java      |  64 ++++++
 .../aspects/session/SessionCountListener.java   |  65 ++++++
 .../session/SessionCountListenerAspect.java     |  68 ++++++
 .../main/resources/wicket-metrics.template.xml  |  12 +-
 .../src/docs/guide/monitoring/monitoring_1.gdoc |  22 +-
 .../src/docs/guide/monitoring/monitoring_2.gdoc |   2 +-
 10 files changed, 432 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/pom.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/pom.xml b/wicket-experimental/wicket-metrics/pom.xml
index 9e81062..d2e8e4a 100644
--- a/wicket-experimental/wicket-metrics/pom.xml
+++ b/wicket-experimental/wicket-metrics/pom.xml
@@ -46,5 +46,9 @@
 			<groupId>io.dropwizard.metrics</groupId>
 			<artifactId>metrics-core</artifactId>
 		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>javax.servlet-api</artifactId>
+		</dependency>
 	</dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetrics.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetrics.java b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetrics.java
index 4b4704d..5d9ae7d 100644
--- a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetrics.java
+++ b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetrics.java
@@ -20,6 +20,7 @@ import org.apache.wicket.Application;
 import org.apache.wicket.MetaDataKey;
 import org.aspectj.lang.ProceedingJoinPoint;
 
+import com.codahale.metrics.Counter;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.Timer.Context;
 
@@ -32,6 +33,29 @@ import com.codahale.metrics.Timer.Context;
 public class WicketMetrics
 {
 
+	private static final String APPLICATION_NAME_PROPERTY = "wicket.applicationName";
+
+	private static final String METRICS_STATIC_REGISTRATION = "wicket.metrics.staticRegistration";
+	/**
+	 * if the application has been resolved
+	 */
+	private static boolean applicationResolved;
+
+	/**
+	 * The application
+	 */
+	private static Application application;
+
+	/**
+	 * Fall back if the application couldn't be resolved the registry is stored static
+	 */
+	private static MetricRegistry metricRegistry;
+
+	/**
+	 * Fall back if the application couldn't be resolved the settings are stored static
+	 */
+	private static WicketMetricsSettings wicketMetricsSettings;
+
 	/** The key for metrics registry **/
 	public static final MetaDataKey<MetricRegistry> METRIC_REGISTRY = new MetaDataKey<MetricRegistry>()
 	{
@@ -51,19 +75,44 @@ public class WicketMetrics
 	 *            the name of the timer context
 	 * @param joinPoint
 	 *            the joinPoint to be proceed
+	 * 
 	 * @return the value of the join point
 	 * @throws Throwable
 	 *             if there is an exception while execution
+	 * @see #org.apache.wicket.metrics.WicketMetrics.measureTime(String, ProceedingJoinPoint,
+	 *      boolean)
 	 */
 	public Object measureTime(String name, ProceedingJoinPoint joinPoint) throws Throwable
 	{
+		return this.measureTime(name, joinPoint, true);
+	}
+
+	/**
+	 * Simply measure the time for a {@literal @}around
+	 * 
+	 * @param name
+	 *            the name of the timer context
+	 * @param joinPoint
+	 *            the joinPoint to be proceed
+	 * @param renderClass
+	 *            if the class name should be rendered behind the metric path
+	 * 
+	 * @return the value of the join point
+	 * @throws Throwable
+	 *             if there is an exception while execution
+	 */
+	public Object measureTime(String name, ProceedingJoinPoint joinPoint, boolean renderClass)
+		throws Throwable
+	{
 		WicketMetricsSettings settings = getSettings();
 		MetricRegistry registry = getMetricRegistry();
 
 		if (settings.isEnabled())
 		{
 			Context context = registry
-				.timer(settings.getPrefix() + name + renderClassName(joinPoint)).time();
+				.timer(
+					settings.getPrefix() + name + (renderClass ? renderClassName(joinPoint) : ""))
+				.time();
 			try
 			{
 				return joinPoint.proceed();
@@ -80,6 +129,63 @@ public class WicketMetrics
 	}
 
 	/**
+	 * 
+	 * @author Tobias Soloschenko
+	 *
+	 */
+	public enum CounterOperation {
+		/**
+		 * Increments
+		 */
+		INC,
+		/**
+		 * Decrements
+		 */
+		DEC
+	}
+
+	/**
+	 * Creates a histogram of the given arguments
+	 * 
+	 * @param name
+	 *            the name of the meter to be marked
+	 * @param joinPoint
+	 *            the join point
+	 * @param counterOperation
+	 *            the operation
+	 * @param value
+	 *            the value to update the counter
+	 * @return the result of the proceeded join point
+	 * @throws Throwable
+	 */
+	public Object counter(String name, ProceedingJoinPoint joinPoint,
+		CounterOperation counterOperation, Long value) throws Throwable
+	{
+		WicketMetricsSettings settings = getSettings();
+		MetricRegistry registry = getMetricRegistry();
+
+		if (settings.isEnabled())
+		{
+			Counter counter = registry
+				.counter(settings.getPrefix() + name + renderClassName(joinPoint));
+			if (counterOperation == CounterOperation.INC)
+			{
+				counter.inc(value);
+			}
+			else
+			{
+				counter.dec(value);
+			}
+		}
+		if (joinPoint != null)
+		{
+			return joinPoint.proceed();
+		}
+		return null;
+	}
+
+
+	/**
 	 * Marks the meter with the given name
 	 * 
 	 * @param name
@@ -128,7 +234,7 @@ public class WicketMetrics
 	 */
 	public String renderClassName(ProceedingJoinPoint joinPoint)
 	{
-		return joinPoint != null
+		return joinPoint != null && joinPoint.getTarget() != null
 			? "/" + joinPoint.getTarget().getClass().getName().replace('.', '_') : "";
 	}
 
@@ -137,16 +243,31 @@ public class WicketMetrics
 	 * 
 	 * @return the metric registry
 	 */
-	private static synchronized MetricRegistry getMetricRegistry()
+	public static synchronized MetricRegistry getMetricRegistry()
 	{
-		Application application = Application.get();
-		MetricRegistry metricRegistry = application.getMetaData(METRIC_REGISTRY);
-		if (metricRegistry == null)
+		if (!applicationResolved)
+		{
+			application = getApplication();
+			applicationResolved = true;
+		}
+		if (application != null && System.getProperty(METRICS_STATIC_REGISTRATION) == null)
+		{
+			MetricRegistry metricRegistry = application.getMetaData(METRIC_REGISTRY);
+			if (metricRegistry == null)
+			{
+				metricRegistry = new MetricRegistry();
+				application.setMetaData(METRIC_REGISTRY, metricRegistry);
+			}
+			return metricRegistry;
+		}
+		else
 		{
-			metricRegistry = new MetricRegistry();
-			application.setMetaData(METRIC_REGISTRY, metricRegistry);
+			if (WicketMetrics.metricRegistry == null)
+			{
+				WicketMetrics.metricRegistry = new MetricRegistry();
+			}
+			return WicketMetrics.metricRegistry;
 		}
-		return metricRegistry;
 	}
 
 	/**
@@ -154,15 +275,79 @@ public class WicketMetrics
 	 * 
 	 * @return the wicket metrics settings
 	 */
-	private static synchronized WicketMetricsSettings getSettings()
+	public static synchronized WicketMetricsSettings getSettings()
+	{
+		if (!applicationResolved)
+		{
+			application = getApplication();
+			applicationResolved = true;
+		}
+		if (application != null && System.getProperty(METRICS_STATIC_REGISTRATION) == null)
+		{
+			WicketMetricsSettings wicketMetricsSettings = application.getMetaData(METRIC_SETTINGS);
+			if (wicketMetricsSettings == null)
+			{
+				wicketMetricsSettings = new WicketMetricsSettings();
+				application.setMetaData(METRIC_SETTINGS, wicketMetricsSettings);
+			}
+			return wicketMetricsSettings;
+		}
+		else
+		{
+			if (wicketMetricsSettings == null)
+			{
+				wicketMetricsSettings = new WicketMetricsSettings();
+			}
+			return wicketMetricsSettings;
+		}
+	}
+
+	/**
+	 * Gets the application. First it tries to resolve the application with Application.get(String)
+	 * - the String is resolved by the system property "wicket.applicationName". If the application
+	 * can't be found by the corresponding name a Application.get() will be invoked to resolve it.
+	 * 
+	 * 
+	 * @return the application or null if the application can't be resolved via get() or get(String)
+	 */
+	private static Application getApplication()
+	{
+		Application application = getApplicationBySystemProperty();
+		if (application == null)
+		{
+			application = getApplicationFromThreadLocal();
+		}
+		return application;
+	}
+
+	/**
+	 * Gets the application from thread local
+	 * 
+	 * @return the application or null if not available
+	 */
+	private static Application getApplicationFromThreadLocal()
+	{
+		Application application = null;
+		if (Application.exists())
+		{
+			application = Application.get();
+		}
+		return application;
+	}
+
+	/**
+	 * Gets the application by the system property wicket.applicationName
+	 * 
+	 * @return the application or null if not available
+	 */
+	private static Application getApplicationBySystemProperty()
 	{
-		Application application = Application.get();
-		WicketMetricsSettings metricRegistry = application.getMetaData(METRIC_SETTINGS);
-		if (metricRegistry == null)
+		Application application = null;
+		String applicatioName = System.getProperty(APPLICATION_NAME_PROPERTY);
+		if (applicatioName != null)
 		{
-			metricRegistry = new WicketMetricsSettings();
-			application.setMetaData(METRIC_SETTINGS, metricRegistry);
+			application = Application.get(applicatioName);
 		}
-		return metricRegistry;
+		return application;
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetricsSettings.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetricsSettings.java b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetricsSettings.java
index 1bbaef2..37d5980 100644
--- a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetricsSettings.java
+++ b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/WicketMetricsSettings.java
@@ -16,8 +16,6 @@
  */
 package org.apache.wicket.metrics;
 
-import org.apache.wicket.Application;
-
 import com.codahale.metrics.JmxReporter;
 import com.codahale.metrics.MetricRegistry;
 
@@ -70,8 +68,7 @@ public class WicketMetricsSettings
 	 */
 	public void startJmxReporter()
 	{
-		MetricRegistry metricRegistry = Application.get()
-			.getMetaData(WicketMetrics.METRIC_REGISTRY);
+		MetricRegistry metricRegistry = WicketMetrics.getMetricRegistry();
 		JmxReporter.forRegistry(metricRegistry).build().start();
 	}
 
@@ -80,8 +77,7 @@ public class WicketMetricsSettings
 	 */
 	public void stopJmxReporter()
 	{
-		MetricRegistry metricRegistry = Application.get()
-			.getMetaData(WicketMetrics.METRIC_REGISTRY);
+		MetricRegistry metricRegistry = WicketMetrics.getMetricRegistry();
 		JmxReporter.forRegistry(metricRegistry).build().stop();
 	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleAspect.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleAspect.java b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleAspect.java
index f7f7c0c..c19af45 100644
--- a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleAspect.java
+++ b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleAspect.java
@@ -31,8 +31,7 @@ public class WicketFilterRequestCycleAspect extends WicketMetrics
 {
 
 	/**
-	 * Collects data how often a request has been made against the webapp and counts the time how
-	 * long the request remains
+	 * Collects the time how long a request took to be processed
 	 * 
 	 * @param joinPoint
 	 *            the joinPoint to be proceed

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleUrlAspect.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleUrlAspect.java b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleUrlAspect.java
new file mode 100644
index 0000000..3cf633e
--- /dev/null
+++ b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/WicketFilterRequestCycleUrlAspect.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.metrics.aspects;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.wicket.metrics.WicketMetrics;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+/**
+ * Aspect to measure request url time
+ * 
+ * @author Tobias Soloschenko
+ */
+@Aspect
+public class WicketFilterRequestCycleUrlAspect extends WicketMetrics
+{
+	/**
+	 * Collects data how often a request has been made against the webapp and counts the time how
+	 * long the request took. Measures the information with the request url
+	 * 
+	 * @param joinPoint
+	 *            the joinPoint to be proceed
+	 * @return returns the boolean of the processRequest method
+	 * 
+	 * @throws Throwable
+	 *             might occur while invoking process request
+	 */
+	@Around("execution(* org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(..))")
+	public Object aroundRequestProcessedWithURL(ProceedingJoinPoint joinPoint) throws Throwable
+	{
+		Object[] args = joinPoint.getArgs();
+		if (args.length >= 3)
+		{
+			Object requestAsObject = args[2];
+			if (requestAsObject != null && requestAsObject instanceof HttpServletRequest)
+			{
+				HttpServletRequest httpServletRequest = (HttpServletRequest)requestAsObject;
+				String requestUrl = httpServletRequest.getRequestURL().toString();
+				String replacedUrl = requestUrl.replace('/', '_');
+				replacedUrl = replacedUrl.replace('.', '_');
+				replacedUrl = replacedUrl.replaceAll(";jsessionid=.*?(?=\\?|$)", "");
+				return measureTime("core/application/request/" + replacedUrl, joinPoint, false);
+			}
+		}
+		return joinPoint.proceed();
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListener.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListener.java b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListener.java
new file mode 100644
index 0000000..6aacfee
--- /dev/null
+++ b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListener.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.metrics.aspects.session;
+
+import javax.servlet.annotation.WebListener;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+
+/**
+ * Listener that counts the current active sessions
+ * 
+ * @author Tobias Soloschenko
+ *
+ */
+@WebListener
+public class SessionCountListener implements HttpSessionListener
+{
+
+	@Override
+	public void sessionDestroyed(HttpSessionEvent event)
+	{
+		dec(event);
+	}
+
+	@Override
+	public void sessionCreated(HttpSessionEvent event)
+	{
+		inc(event);
+	}
+
+	/**
+	 * Used to wire an aspect around
+	 * 
+	 * @param event the http session event
+	 */
+	public void dec(HttpSessionEvent event)
+	{
+		// NOOP for aspect usage
+	}
+	
+	/**
+	 * Used to wire an aspect around
+	 * 
+	 * @param event the http session event
+	 */
+	public void inc(HttpSessionEvent event)
+	{
+		// NOOP for aspect usage
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListenerAspect.java
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListenerAspect.java b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListenerAspect.java
new file mode 100644
index 0000000..7dc8f04
--- /dev/null
+++ b/wicket-experimental/wicket-metrics/src/main/java/org/apache/wicket/metrics/aspects/session/SessionCountListenerAspect.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.metrics.aspects.session;
+
+import org.apache.wicket.metrics.WicketMetrics;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+/**
+ * The Session count listener aspect measures how many sessions are active
+ * 
+ * @author Tobias Soloschenko
+ *
+ */
+@Aspect
+public class SessionCountListenerAspect extends WicketMetrics
+{
+
+	/**
+	 * Measures if a session is going to be activated
+	 * 
+	 * @param joinPoint
+	 *            the join point
+	 * @return void
+	 * @throws Throwable
+	 *             if an error occurred 
+	 */
+	@Around("execution(* org.apache.wicket.metrics.aspects.session.SessionCountListener.inc(..))")
+	public Object aroundInc(ProceedingJoinPoint joinPoint) throws Throwable
+	{
+		Object count = joinPoint.proceed();
+		counter("core/session/count", null, CounterOperation.INC, 1L);
+		return count;
+	}
+	
+	/**
+	 * Measures if a session is going to be destroyed
+	 * 
+	 * @param joinPoint
+	 *            the join point
+	 * @return void
+	 * @throws Throwable
+	 *             if an error occurred
+	 */
+	@Around("execution(* org.apache.wicket.metrics.aspects.session.SessionCountListener.dec(..))")
+	public Object aroundDec(ProceedingJoinPoint joinPoint) throws Throwable
+	{
+		Object count = joinPoint.proceed();
+		counter("core/session/count", null, CounterOperation.DEC, 1L);
+		return count;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-experimental/wicket-metrics/src/main/resources/wicket-metrics.template.xml
----------------------------------------------------------------------
diff --git a/wicket-experimental/wicket-metrics/src/main/resources/wicket-metrics.template.xml b/wicket-experimental/wicket-metrics/src/main/resources/wicket-metrics.template.xml
index 377e451..5ea5b30 100644
--- a/wicket-experimental/wicket-metrics/src/main/resources/wicket-metrics.template.xml
+++ b/wicket-experimental/wicket-metrics/src/main/resources/wicket-metrics.template.xml
@@ -1,14 +1,14 @@
 
 <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
 <aspectj>
-    <weaver options="-nowarn">
+    <weaver options="-nowarn"><!-- -verbose -showWeaveInfo -->
         <include within="org.apache.wicket..*"/>
     </weaver>
     <aspects>
-    	<aspect name="org.apache.wicket.metrics.aspects.model.LoadableDetachableModelLoadAspect" />
-    	<aspect name="org.apache.wicket.metrics.aspects.requesthandler.IRequestHandlerDetachAspect" />
-    	<aspect name="org.apache.wicket.metrics.aspects.requesthandler.IRequestHandlerRespondAspect" />
-    	<aspect name="org.apache.wicket.metrics.aspects.resource.IResourceCreateAspect" />
+		<aspect name="org.apache.wicket.metrics.aspects.model.LoadableDetachableModelLoadAspect" />
+		<aspect name="org.apache.wicket.metrics.aspects.requesthandler.IRequestHandlerDetachAspect" />
+		<aspect name="org.apache.wicket.metrics.aspects.requesthandler.IRequestHandlerRespondAspect" />
+ 		<aspect name="org.apache.wicket.metrics.aspects.resource.IResourceCreateAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.behavior.BehaviorCreateAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.component.ComponentCreateAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.component.ComponentOnConfigureAspect" />
@@ -21,6 +21,8 @@
 		<aspect name="org.apache.wicket.metrics.aspects.ajax.IPartialPageRequestHandlerPrependJavaScriptAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.resource.ResourceReferenceCreateAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.markup.WicketTagCreateAspect" />
+		<aspect name="org.apache.wicket.metrics.aspects.WicketFilterRequestCycleUrlAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.WicketFilterRequestCycleAspect" />
+		<aspect name="org.apache.wicket.metrics.aspects.session.SessionCountListenerAspect" />
     </aspects>
 </aspectj>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-user-guide/src/docs/guide/monitoring/monitoring_1.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/monitoring/monitoring_1.gdoc b/wicket-user-guide/src/docs/guide/monitoring/monitoring_1.gdoc
index 6d41935..603ca58 100644
--- a/wicket-user-guide/src/docs/guide/monitoring/monitoring_1.gdoc
+++ b/wicket-user-guide/src/docs/guide/monitoring/monitoring_1.gdoc
@@ -38,6 +38,7 @@ This is a little example how to setup wicket-metrics within a Apache Tomcat.
 		<aspect name="org.apache.wicket.metrics.aspects.resource.ResourceReferenceCreateAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.markup.WicketTagCreateAspect" />
 		<aspect name="org.apache.wicket.metrics.aspects.WicketFilterRequestCycleAspect" />
+		<aspect name="org.apache.wicket.metrics.aspects.session.SessionCountListenerAspect" />
     </aspects>
 </aspectj>
 {code}
@@ -46,19 +47,34 @@ This is a little example how to setup wicket-metrics within a Apache Tomcat.
 
 * For the weaver options refer to the "AspectJ LTW configuration documentation":https://eclipse.org/aspectj/doc/next/devguide/ltw-configuration.html
 
+* If you use the SessionCountListenerAspect you have to ensure that metadata-complete="false" is set otherwise you have to add the listener yourself:
+{code}
+<listener>
+	<listener-class>org.apache.wicket.metrics.aspects.session.SessionCountListener</listenerclass>
+</listener>
+{code}
+
+You also have to clear the session store if you restart the server - otherwise physically stored session will corrupt the data, because the count is initialized with 0.
+
 (5 - optional) To enable the JMX measurement write the following line into your init method of your Application (Now you are able to connect with jvisualvm to your server and have a look at the data):
 {code}
-Application.get().getMetaData(WicketMetrics.METRIC_SETTINGS).startJmxReporter();
+WicketMetrics.getSettings().startJmxReporter();
 {code}
 
 To deactivate:
 {code}
-Application.get().getMetaData(WicketMetrics.METRIC_SETTINGS).stopJmxReporter();
+WicketMetrics.getSettings().stopJmxReporter();
 {code}
 
 To disable measurement:
 {code}
-Application.get().getMetaData(WicketMetrics.METRIC_SETTINGS).setEnable(false);
+WicketMetrics.getSettings().setEnable(false);
 {code}
 
+(6 - optional) There are two system flags which can be applied to the start of the server
+
+-Dwicket.metrics.staticRegistration=true - If this argument is set the wicket metrics settings and the metrics registry are stored in static variables within the WicketMetrics class - this might cause problems in an osgi environment
+
+-dwicket.applicationName=<filtername> - If this argument is set no ThreadLocal access is required, because the Application is received via get(String). Needs to be set if the session should be measured SessionCountListenerAspect
+
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/50b6cadc/wicket-user-guide/src/docs/guide/monitoring/monitoring_2.gdoc
----------------------------------------------------------------------
diff --git a/wicket-user-guide/src/docs/guide/monitoring/monitoring_2.gdoc b/wicket-user-guide/src/docs/guide/monitoring/monitoring_2.gdoc
index 0bd18b2..42e4748 100644
--- a/wicket-user-guide/src/docs/guide/monitoring/monitoring_2.gdoc
+++ b/wicket-user-guide/src/docs/guide/monitoring/monitoring_2.gdoc
@@ -18,7 +18,7 @@ To visualize the metrics with Graphite a little additional configuration is requ
 	@Override
 	protected void init()
 	{
-		MetricRegistry metricRegistry = this.getMetaData(WicketMetrics.METRIC_REGISTRY);
+		MetricRegistry metricRegistry = WicketMetrics.getMetricRegistry();
 		final Graphite graphite = new Graphite(new InetSocketAddress("127.0.0.1", 2003));
 		reporter = GraphiteReporter.forRegistry(metricRegistry).prefixedWith("WebApplications")
 			.convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS)