You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jc...@apache.org on 2006/11/10 22:49:47 UTC

svn commit: r473517 - in /incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket: ./ protocol/http/ protocol/http/portlet/ protocol/http/request/

Author: jcompagner
Date: Fri Nov 10 13:49:46 2006
New Revision: 473517

URL: http://svn.apache.org/viewvc?view=rev&rev=473517
Log:
request logger changes

Added:
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/IRequestLogger.java
Modified:
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Application.java
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/ClientProperties.java
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/MockWebApplication.java
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/RequestLogger.java
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WebApplication.java
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WicketServlet.java
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/portlet/PortletApplication.java
    incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/request/WebClientInfo.java

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Application.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Application.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Application.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/Application.java Fri Nov 10 13:49:46 2006
@@ -43,6 +43,8 @@
 import wicket.markup.resolver.ParentResolver;
 import wicket.markup.resolver.WicketLinkResolver;
 import wicket.markup.resolver.WicketMessageResolver;
+import wicket.protocol.http.IRequestLogger;
+import wicket.protocol.http.RequestLogger;
 import wicket.session.ISessionStore;
 import wicket.settings.IAjaxSettings;
 import wicket.settings.IApplicationSettings;
@@ -52,6 +54,7 @@
 import wicket.settings.IMarkupSettings;
 import wicket.settings.IPageSettings;
 import wicket.settings.IRequestCycleSettings;
+import wicket.settings.IRequestLoggerSettings;
 import wicket.settings.IResourceSettings;
 import wicket.settings.ISecuritySettings;
 import wicket.settings.ISessionSettings;
@@ -235,6 +238,9 @@
 	/** The session facade. */
 	private ISessionStore sessionStore;
 
+	/** Request logger instance. */
+	private IRequestLogger requestLogger;
+	
 	/** Settings for this application. */
 	private Settings settings;
 
@@ -280,7 +286,36 @@
 			}
 		});
 	}
-
+	
+	/**
+	 * Gets the {@link RequestLogger}.
+	 * 
+	 * @return The RequestLogger
+	 */
+	public final IRequestLogger getRequestLogger()
+	{
+		if(getRequestLoggerSettings().isRequestLoggerEnabled())
+		{
+			if(requestLogger == null) requestLogger = newRequestLogger();
+		}
+		else
+		{
+			requestLogger = null;
+		}
+		return requestLogger;
+	}	
+	
+	/**
+	 * creates a new request logger when requests logging is enabled.
+	 * 
+	 * @return  The new request logger
+	 * 
+	 */
+	protected IRequestLogger newRequestLogger()
+	{
+		return new RequestLogger();
+	}
+	
 	/**
 	 * Adds a component instantiation listener. This method should typicaly only
 	 * be called during application startup; it is not thread safe.
@@ -550,6 +585,15 @@
 		return getSettings();
 	}
 
+	/**
+	 * @return Application's resources related settings
+	 * @see IResourceSettings
+	 * @since 1.3
+	 */
+	public final IRequestLoggerSettings getRequestLoggerSettings()
+	{
+		return getSettings();
+	}
 	/**
 	 * @return Application's security related settings
 	 * @see ISecuritySettings

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/ClientProperties.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/ClientProperties.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/ClientProperties.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/ClientProperties.java Fri Nov 10 13:49:46 2006
@@ -341,7 +341,14 @@
 	 */
 	public static final String UTC_OFFSET = "utcOffset";
 
+	
+	/**
+	 * The client's remote/ip address
+	 */
+	public static final String REMOTE_ADDRESS = "remoteAddress";
+
 	private static final long serialVersionUID = 1L;
+
 
 	/**
 	 * The actual property data.

Added: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/IRequestLogger.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/IRequestLogger.java?view=auto&rev=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/IRequestLogger.java (added)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/IRequestLogger.java Fri Nov 10 13:49:46 2006
@@ -0,0 +1,122 @@
+/*
+ * $Id: org.eclipse.jdt.ui.prefs 5004 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 2006) eelco12 $
+ * $Revision: 5004 $
+ * $Date: 2006-03-17 20:47:08 -0800 (Fri, 17 Mar 2006) $
+ * 
+ * ==============================================================================
+ * Licensed 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 wicket.protocol.http;
+
+import java.util.List;
+
+import wicket.Application;
+import wicket.IRequestTarget;
+import wicket.protocol.http.RequestLogger.SessionData;
+import wicket.session.ISessionStore;
+
+
+/**
+ * Interface for the request logger and viewer.
+ * @see Application#setRequestLogger(IRequestLogger)
+ * 
+ * @author jcompagner
+ */
+public interface IRequestLogger
+{
+
+	/**
+	 * @return The total created sessions counter
+	 */
+	public abstract int getTotalCreatedSessions();
+
+	/**
+	 * @return The peak sessions counter
+	 */
+	public abstract int getPeakSessions();
+
+	/**
+	 * This method returns a List of the current requests that are in mem.
+	 * This is a readonly list.
+	 * 
+	 * @return Collection of the current requests
+	 */
+	public abstract List getRequests();
+	
+	
+	/**
+	 * @return Collection of live Sessions Data
+	 */
+	public SessionData[] getLiveSessions();
+
+	/**
+	 * called when the session is created and has an id. 
+	 * (for http it means that the http session is created)
+	 * 
+	 * @param id
+	 */
+	public abstract void sessionCreated(String id);
+
+	/**
+	 * Method used to cleanup a livesession when the session was
+	 * invalidated by the webcontainer
+	 * 
+	 * @param sessionId
+	 */
+	public abstract void sessionDestroyed(String sessionId);
+
+	/**
+	 * This method is called when the request is over this will
+	 * set the total time a request takes and cleans up the current 
+	 * request data.
+	 * 
+	 * @param timeTaken
+	 */
+	public abstract void requestTime(long timeTaken);
+
+	/**
+	 * Called to monitor removals of objects out of the {@link ISessionStore}
+	 * 
+	 * @param value
+	 */
+	public abstract void objectRemoved(Object value);
+
+	/**
+	 * Called to monitor updates of objects in the {@link ISessionStore}
+	 * 
+	 * @param value
+	 */
+	public abstract void objectUpdated(Object value);
+
+	/**
+	 * Called to monitor additions of objects in the {@link ISessionStore}
+	 * 
+	 * @param value
+	 */
+	public abstract void objectCreated(Object value);
+
+	/**
+	 * Sets the target that was the response target for the current request
+	 * 
+	 * @param target
+	 */
+	public abstract void logResponseTarget(IRequestTarget target);
+
+	/**
+	 * Sets the target that was the event target for the current request
+	 * 
+	 * @param target
+	 */
+	public abstract void logEventTarget(IRequestTarget target);
+
+}
\ No newline at end of file

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/MockWebApplication.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/MockWebApplication.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/MockWebApplication.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/MockWebApplication.java Fri Nov 10 13:49:46 2006
@@ -209,19 +209,6 @@
 	}
 
 	/**
-	 * Get the context object so that we can apply configurations to it. This
-	 * method always returns an instance of <code>MockServletContext</code>,
-	 * so it is fine to cast the result to this class in order to get access to
-	 * the set methods.
-	 * 
-	 * @return The servlet context
-	 */
-	public ServletContext getServletContext()
-	{
-		return context;
-	}
-
-	/**
 	 * Get the request object so that we can apply configurations to it.
 	 * 
 	 * @return The request object

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/RequestLogger.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/RequestLogger.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/RequestLogger.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/RequestLogger.java Fri Nov 10 13:49:46 2006
@@ -38,12 +38,15 @@
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import wicket.util.concurrent.ConcurrentHashMap;
 
+import wicket.Application;
 import wicket.IRequestTarget;
 import wicket.Page;
 import wicket.PageMap;
@@ -52,8 +55,6 @@
 import wicket.request.target.component.IPageRequestTarget;
 import wicket.request.target.component.listener.IListenerInterfaceRequestTarget;
 import wicket.request.target.resource.ISharedResourceRequestTarget;
-import wicket.session.ISessionStore;
-import wicket.util.concurrent.ConcurrentHashMap;
 import wicket.util.lang.Classes;
 import wicket.util.string.AppendingStringBuffer;
 
@@ -75,27 +76,65 @@
  * 
  * @since 1.2
  */
-public class RequestLogger
+public class RequestLogger implements IRequestLogger
 {
 	// TODO post 1.2 for this class: saving to a log file, only holding a small part in mem.
+
 	
-	
+	/**
+	 * This interface can be implemented in a custom session object.
+	 * to give an object that has more information for the current session 
+	 * (state of session).
+	 * 
+	 * @author jcompagner
+	 */
+	public interface ISessionLogInfo
+	{
+
+		/**
+		 * @return The custom object stored in the request loggers current request.
+		 */
+		Object getSessionInfo();
+
+	}
+
+
 	private int totalCreatedSessions;
 	
 	private int peakSessions;
 	
+	private List requests;
+
 	private Map liveSessions;
+
+	private ThreadLocal currentRequest = new ThreadLocal();
 	
 	/**
 	 * Construct.
 	 */
 	public RequestLogger()
 	{
+		requests = Collections.synchronizedList(new LinkedList()
+		{
+			private static final long serialVersionUID = 1L;
+
+			/**
+			 * @see java.util.LinkedList#add(java.lang.Object)
+			 */
+			public void add(int index,Object o)
+			{
+				super.add(index,o);
+				if(size() > Application.get().getRequestLoggerSettings().getRequestsWindowSize())
+				{
+					removeLast();
+				}
+			}
+		});
 		liveSessions = new ConcurrentHashMap();
 	}
 
 	/**
-	 * @return The total created sessions counter
+	 * @see wicket.protocol.http.IRequestLogger#getTotalCreatedSessions()
 	 */
 	public int getTotalCreatedSessions()
 	{
@@ -103,7 +142,7 @@
 	}
 	
 	/**
-	 * @return The peak sessions counter
+	 * @see wicket.protocol.http.IRequestLogger#getPeakSessions()
 	 */
 	public int getPeakSessions()
 	{
@@ -111,18 +150,22 @@
 	}
 	
 	/**
-	 * @return Collection of live Sessions
+	 * @see wicket.protocol.http.IRequestLogger#getRequests()
 	 */
-	public Collection getLiveSessions()
+	public List getRequests()
 	{
-		return liveSessions.values();
+		return Collections.unmodifiableList(requests);
+	}
+	
+	public SessionData[] getLiveSessions()
+	{
+		SessionData[] sessions = (SessionData[])liveSessions.values().toArray(new SessionData[liveSessions.size()]);
+		Arrays.sort(sessions);
+		return sessions;
 	}
 
 	/**
-	 * Method used to cleanup a livesession when the session was
-	 * invalidated by the webcontainer
-	 * 
-	 * @param sessionId
+	 * @see wicket.protocol.http.IRequestLogger#sessionDestroyed(java.lang.String)
 	 */
 	public void sessionDestroyed(String sessionId)
 	{
@@ -130,420 +173,398 @@
 	}
 
 	/**
-	 * This method is called when the request is over this will
-	 * set the total time a request takes and cleans up the current 
-	 * request data.
-	 * 
-	 * @param timeTaken
+	 * @see wicket.protocol.http.IRequestLogger#sessionDestroyed(java.lang.String)
+	 */
+	public void sessionCreated(String sessionId)
+	{
+		liveSessions.put(sessionId, new SessionData(sessionId));
+		if(liveSessions.size() > peakSessions) peakSessions = liveSessions.size();
+		totalCreatedSessions++;
+	}
+	
+	RequestData getCurrentRequest()
+	{
+		RequestData rd = (RequestData)currentRequest.get();
+		if(rd == null)
+		{
+			rd = new RequestData();
+			currentRequest.set(rd);
+		}
+		return rd;
+	}
+
+	/**
+	 * @see wicket.protocol.http.IRequestLogger#requestTime(long)
 	 */
 	public void requestTime(long timeTaken)
 	{
-		SessionData sd = getSessionData();
-		sd.endRequest(timeTaken);
+		RequestData rd = (RequestData)currentRequest.get();
+		if(rd != null)
+		{
+			Session session = Session.get();
+			String sessionId = session.getId();
+			rd.setSessionId(sessionId);
+			
+			Object sessionInfo = getSessionInfo(session);
+			rd.setSessionInfo(sessionInfo);
+			
+			long sizeInBytes = -1;
+			if(Application.get().getRequestLoggerSettings().getRecordSessionSize())
+			{
+				sizeInBytes = session.getSizeInBytes();
+			}
+			rd.setSessionSize(sizeInBytes);
+			rd.setTimeTaken(timeTaken);
+			requests.add(0, rd);
+			currentRequest.set(null);
+			if(sessionId != null)
+			{
+				SessionData sd = (SessionData)liveSessions.get(sessionId);
+				if(sd == null)
+				{
+					// passivated session or logger only started after it.
+					sessionCreated(sessionId);
+					sd = (SessionData)liveSessions.get(sessionId);
+				}
+				if(sd != null)
+				{
+					sd.setSessionInfo(sessionInfo);
+					sd.setSessionSize(sizeInBytes);
+					sd.addTimeTaken(timeTaken);
+				}
+			}
+		}
 	}
 	
+	private Object getSessionInfo(Session session)
+	{
+		if (session instanceof ISessionLogInfo)
+		{
+			return ((ISessionLogInfo)session).getSessionInfo();
+		}
+		return "";
+	}
+
 	/**
-	 * Called to monitor removals of objects out of the {@link ISessionStore}
-	 * 
-	 * @param value
+	 * @see wicket.protocol.http.IRequestLogger#objectRemoved(java.lang.Object)
 	 */
 	public void objectRemoved(Object value)
 	{
-		SessionData sd = getSessionData();
+		RequestData rd = getCurrentRequest();
 		if(value instanceof Page)
 		{
-			sd.pageRemoved((Page)value);
+			Page page = (Page)value;
+			rd.addEntry("Page removed, id: " + page.getId() + ", class:" + page.getClass());
 		}
 		else if(value instanceof PageMap)
 		{
-			sd.pageMapRemoved((PageMap)value);
+			PageMap map = (PageMap)value;
+			rd.addEntry("PageMap removed, name: " + (map.getName()==null?"DEFAULT":map.getName()));
 		}
 		else if(value instanceof WebSession)
 		{
-			sd.webSessionRemoved((WebSession)value);
+			rd.addEntry("Session removed");
 		}
 		else
 		{
-			// unknown object/custom object?
+			rd.addEntry("Custom object removed: " + value);
 		}
 	}
 
 	/**
-	 * Called to monitor updates of objects in the {@link ISessionStore}
-	 * 
-	 * @param value
+	 * @see wicket.protocol.http.IRequestLogger#objectUpdated(java.lang.Object)
 	 */
 	public void objectUpdated(Object value)
 	{
-		SessionData sd = getSessionData();
+		RequestData rd = getCurrentRequest();
 		if(value instanceof Page)
 		{
-			sd.pageUpdated((Page)value);
+			Page page = (Page)value;
+			rd.addEntry("Page updated, id: " + page.getId() + ", class:" + page.getClass());
 		}
 		else if(value instanceof PageMap)
 		{
-			sd.pageMapUpdated((PageMap)value);
+			PageMap map = (PageMap)value;
+			rd.addEntry("PageMap updated, name: " + (map.getName()==null?"DEFAULT":map.getName()));
 		}
-		else if(value instanceof WebSession)
+		else if(value instanceof Session)
 		{
-			sd.webSessionUpdated((WebSession)value);
+			rd.addEntry("Session updated");
 		}
 		else
 		{
-			// unknown object/custom object?
+			rd.addEntry("Custom object updated: " + value);
 		}
-		
 	}
 
 	/**
-	 * Called to monitor additions of objects in the {@link ISessionStore}
-	 * 
-	 * @param value
+	 * @see wicket.protocol.http.IRequestLogger#objectCreated(java.lang.Object)
 	 */
 	public void objectCreated(Object value)
 	{
-		SessionData sd = null;
+		RequestData rd = getCurrentRequest();
 		
-		//ignore the creation of sessions itself. 
-		// Because not much is set then (Session.get()/ RequestCycle.get())
-		if( !(value instanceof Session) )
+		if( value instanceof Session )
 		{
-			sd = getSessionData();
+			rd.addEntry("Session created"); 
 		}
-		if(value instanceof Page)
+		else if(value instanceof Page)
 		{
-			sd.pageCreated((Page)value);
+			Page page = (Page)value;
+			rd.addEntry("Page created, id: " + page.getId() + ", class:" + page.getClass());
 		}
 		else if(value instanceof PageMap)
 		{
-			sd.pageMapCreated((PageMap)value);
+			PageMap map = (PageMap)value;
+			rd.addEntry("PageMap created, name: " + (map.getName()==null?"DEFAULT":map.getName()));
 		}
 		else
 		{
-			// unknown object/custom object?
+			rd.addEntry("Custom object created: " + value);
 		}
 		
 	}
-
+	
 	/**
-	 * Sets the target that was the response target for the current request
-	 * 
-	 * @param target
+	 * @see wicket.protocol.http.IRequestLogger#logResponseTarget(wicket.IRequestTarget)
 	 */
 	public void logResponseTarget(IRequestTarget target)
 	{
-		getSessionData().logResponseTarget(target);
+		getCurrentRequest().addResponseTarget(getRequestTargetString(target));
 	}
 
 	/**
-	 * Sets the target that was the event target for the current request
-	 * 
-	 * @param target
+	 * @see wicket.protocol.http.IRequestLogger#logEventTarget(wicket.IRequestTarget)
 	 */
 	public void logEventTarget(IRequestTarget target)
 	{
-		getSessionData().logEventTarget(target);
+		getCurrentRequest().addEventTarget(getRequestTargetString(target));
 	}
 	
-	private SessionData getSessionData()
-	{
-		Session session = Session.get();
-		// TODO when delayed sessions, do make sure this doesn't cause a http session creation.
-		SessionData sessionData = (SessionData)liveSessions.get(session.getId());
-		if(sessionData == null)
-		{
-			sessionData = createSessionData(session);
-		}
-		return sessionData;
-	}
-
+	
 	/**
-	 * @param session
-	 * @return The SessionData object
+	 * @param target
+	 * @return The request target nice display string
 	 */
-	private SessionData createSessionData(Session session)
+	private String getRequestTargetString(IRequestTarget target)
 	{
-		SessionData sessionData = new SessionData(session);
-		liveSessions.put(session.getId(), sessionData);
-		totalCreatedSessions++;
-		if(peakSessions < liveSessions.size())
+		AppendingStringBuffer sb = new AppendingStringBuffer(128);
+		if(target instanceof IListenerInterfaceRequestTarget)
+		{
+			IListenerInterfaceRequestTarget listener = (IListenerInterfaceRequestTarget)target;
+			sb.append("Interface call [target:");
+			sb.append(Classes.simpleName(listener.getTarget().getClass()));
+			sb.append("(");
+			sb.append(listener.getTarget().getId());
+			sb.append("), page: ");
+			sb.append(Classes.simpleName(listener.getPage().getClass()));
+			sb.append("(");
+			sb.append(listener.getPage().getId());
+			sb.append("), interface: ");
+			sb.append(listener.getRequestListenerInterface().getName());
+			sb.append(".");
+			sb.append(listener.getRequestListenerInterface().getMethod().getName());
+			sb.append("]");
+		}
+		else if(target instanceof IPageRequestTarget)
+		{
+			IPageRequestTarget pageRequestTarget = (IPageRequestTarget)target;
+			sb.append("PageRequest call [page: ");
+			sb.append(Classes.simpleName(pageRequestTarget.getPage().getClass()));
+			sb.append("(");
+			sb.append(pageRequestTarget.getPage().getId());
+			sb.append(")]");
+		}
+		else if(target instanceof IBookmarkablePageRequestTarget)
+		{
+			IBookmarkablePageRequestTarget pageRequestTarget = (IBookmarkablePageRequestTarget)target;
+			sb.append("BookmarkablePage call [page: ");
+			sb.append(Classes.simpleName(pageRequestTarget.getPageClass()));
+			sb.append("]");
+		}
+		else if(target instanceof ISharedResourceRequestTarget)
+		{
+			ISharedResourceRequestTarget sharedResourceTarget = (ISharedResourceRequestTarget)target;
+			sb.append("Shared Resource call [resourcekey: ");
+			sb.append(sharedResourceTarget.getResourceKey());
+			sb.append("]");
+		}
+		else
 		{
-			peakSessions = liveSessions.size();
+			sb.append(target.toString());
 		}
-		return sessionData;
+		return sb.toString();
 	}
-
+	
 	/**
-	 * This class hols the information one sessions has
+	 * This class hold the information one request of a session has.
 	 * 
 	 * @author jcompagner
 	 */
-	public static class SessionData implements Serializable
+	public static class SessionData implements Serializable, Comparable
 	{
 		private static final long serialVersionUID = 1L;
-
-		private final Session session;
-		
-		private LinkedList requests;
 		
-		private RequestData currentRequest;
+		private String sessionId;
+		private long startDate;
+		private long lastActive;
+		private long numberOfRequests;
+		private long totalTimeTaken;
+		private long sessionSize;
+		private Object sessionInfo;
 
-		private double totalRequestsTime; 
-		
-		private long lastRequestTime = System.currentTimeMillis();
-		
 		/**
 		 * Construct.
-		 * @param session
+		 * @param sessionId
 		 */
-		public SessionData(Session session)
+		public SessionData(String sessionId)
 		{
-			this.session = session;
-			this.requests = new LinkedList();
+			this.sessionId = sessionId;
+			this.startDate = System.currentTimeMillis(); 
+			this.numberOfRequests = 1;
 		}
 		
 		/**
-		 * @return The session id
+		 * @return The last active date.
 		 */
-		public String getId()
+		public Date getLastActive()
 		{
-			return session.getId();
+			return new Date(lastActive);
 		}
 		
 		/**
-		 * @return The session
+		 * @return The start date of this session
 		 */
-		public Session getSession()
+		public Date getStartDate()
 		{
-			return session;
+			return new Date(startDate);
 		}
 		
 		/**
-		 * Gets lastRequestTime.
-		 * @return lastRequestTime
+		 * @return The number of request for this session
 		 */
-		public long getLastRequestTime()
+		public long getNumberOfRequests()
 		{
-			return lastRequestTime;
+			return numberOfRequests;
 		}
-
 		
 		/**
-		 * @return The request list of this session
+		 * @return Returns the session size.
 		 */
-		public List getRequests()
+		public long getSessionSize()
 		{
-			return requests;
+			return sessionSize;
 		}
 		
 		/**
-		 * @return The total session size
+		 * @return Returns the total time this session has spent.
 		 */
-		public long getSessionSize()
+		public long getTotalTimeTaken()
 		{
-			return session.getSizeInBytes();
+			return totalTimeTaken;
 		}
-
+		
 		/**
-		 * @return The total time in seconds all request did take
+		 * @return The session info object given by the {@link ISessionLogInfo#getSessionInfo()} session method.
 		 */
-		public Double getRequestsTime()
+		public Object getSessionInfo()
 		{
-			return new Double(totalRequestsTime/1000);
+			return sessionInfo;
 		}
 		
 		/**
-		 * @param target
+		 * @return The session id
 		 */
-		public void logEventTarget(IRequestTarget target)
+		public String getSessionId()
 		{
-			getCurrentRequest().addEventTarget(getRequestTargetString(target));
+			return sessionId;
 		}
 		
-		/**
-		 * @param target
-		 */
-		public void logResponseTarget(IRequestTarget target)
+		void addTimeTaken(long time)
 		{
-			getCurrentRequest().addResponseTarget(getRequestTargetString(target));
+			this.lastActive = System.currentTimeMillis();
+			this.numberOfRequests++;
+			this.totalTimeTaken += time;
 		}
 		
-		/**
-		 * @param target
-		 * @return The request target nice display string
-		 */
-		private String getRequestTargetString(IRequestTarget target)
+		void setSessionInfo(Object sessionInfo)
 		{
-			AppendingStringBuffer sb = new AppendingStringBuffer(128);
-			if(target instanceof IListenerInterfaceRequestTarget)
-			{
-				IListenerInterfaceRequestTarget listener = (IListenerInterfaceRequestTarget)target;
-				sb.append("Interface call [target:");
-				sb.append(Classes.simpleName(listener.getTarget().getClass()));
-				sb.append("(");
-				sb.append(listener.getTarget().getId());
-				sb.append("), page: ");
-				sb.append(Classes.simpleName(listener.getPage().getClass()));
-				sb.append("(");
-				sb.append(listener.getPage().getId());
-				sb.append("), interface: ");
-				sb.append(listener.getRequestListenerInterface().getName());
-				sb.append(".");
-				sb.append(listener.getRequestListenerInterface().getMethod().getName());
-				sb.append("]");
-			}
-			else if(target instanceof IPageRequestTarget)
-			{
-				IPageRequestTarget pageRequestTarget = (IPageRequestTarget)target;
-				sb.append("PageRequest call [page: ");
-				sb.append(Classes.simpleName(pageRequestTarget.getPage().getClass()));
-				sb.append("(");
-				sb.append(pageRequestTarget.getPage().getId());
-				sb.append(")]");
-			}
-			else if(target instanceof IBookmarkablePageRequestTarget)
-			{
-				IBookmarkablePageRequestTarget pageRequestTarget = (IBookmarkablePageRequestTarget)target;
-				sb.append("BookmarkablePage call [page: ");
-				sb.append(Classes.simpleName(pageRequestTarget.getPageClass()));
-				sb.append("]");
-			}
-			else if(target instanceof ISharedResourceRequestTarget)
-			{
-				ISharedResourceRequestTarget sharedResourceTarget = (ISharedResourceRequestTarget)target;
-				sb.append("Shared Resource call [resourcekey: ");
-				sb.append(sharedResourceTarget.getResourceKey());
-				sb.append("]");
-			}
-			else
-			{
-				sb.append(target.toString());
-			}
-			return sb.toString();
+			this.sessionInfo = sessionInfo; 
 		}
 		
-		/**
-		 * @param page
-		 */
-		public void pageCreated(Page page)
+		void setSessionSize(long size)
 		{
-			getCurrentRequest().addEntry("Page created, id: " + page.getId() + ", class:" + page.getClass());
+			this.sessionSize = size;
 		}
 
-		/**
-		 * @param map
-		 */
-		public void pageMapCreated(PageMap map)
+		public int compareTo(Object sd)
 		{
-			getCurrentRequest().addEntry("PageMap created, name: " + (map.getName()==null?"DEFAULT":map.getName()));
+			return (int)(((SessionData)sd).lastActive - lastActive);
 		}
 
-		/**
-		 * @param session
-		 */
-		public void webSessionCreated(WebSession session)
-		{
-			getCurrentRequest().addEntry("WebSession created");
-		}
+	}
+	
 
-		/**
-		 * @param session
-		 */
-		public void webSessionUpdated(WebSession session)
-		{
-			getCurrentRequest().addEntry("WebSession updated");
-		}
+	/**
+	 * This class hold the information one request of a session has.
+	 * 
+	 * @author jcompagner
+	 */
+	public static class RequestData implements Serializable
+	{
+		private static final long serialVersionUID = 1L;
 
-		/**
-		 * @param map
-		 */
-		public void pageMapUpdated(PageMap map)
-		{
-			getCurrentRequest().addEntry("PageMap updated, name: " + (map.getName()==null?"DEFAULT":map.getName()));
-		}
+		private long startDate;
+		private long timeTaken;
+		private List entries = new ArrayList(5);
+		private String eventTarget;
+		private String responseTarget;
 
-		/**
-		 * @param page
-		 */
-		public void pageUpdated(Page page)
-		{
-			getCurrentRequest().addEntry("Page updated, id: " + page.getId() + ", class:" + page.getClass());
-		}
+		private String sessionId;
 
-		/**
-		 * @param session
-		 */
-		public void webSessionRemoved(WebSession session)
-		{
-			getCurrentRequest().addEntry("WebSession removed");
-		}
+		private long totalSessionSize;
 
+		private Object sessionInfo;
+		
 		/**
-		 * @param map
+		 * @return The time taken for this request
 		 */
-		public void pageMapRemoved(PageMap map)
+		public Long getTimeTaken()
 		{
-			getCurrentRequest().addEntry("PageMap removed, name: " + (map.getName()==null?"DEFAULT":map.getName()));
+			return new Long(timeTaken);
 		}
 
 		/**
-		 * @param page
+		 * @return The session object info, created by {@link ISessionLogInfo#getSessionInfo()}
 		 */
-		public void pageRemoved(Page page)
+		public Object getSessionInfo()
 		{
-			getCurrentRequest().addEntry("Page removed, id: " + page.getId() + ", class:" + page.getClass());
+			return sessionInfo;
 		}
 		
 		/**
-		 * @param timeTaken
+		 * Set the session info object of the session for this request.
+		 * @param sessionInfo
 		 */
-		public void endRequest(long timeTaken)
+		public void setSessionInfo(Object sessionInfo)
 		{
-			RequestData rd = getCurrentRequest();
-			rd.setTimeTaken(timeTaken);
-			totalRequestsTime += timeTaken;
-			currentRequest = null;
-			
-			lastRequestTime = new Date().getTime() - timeTaken;
+			this.sessionInfo = sessionInfo;
 		}
-		
-		private RequestData getCurrentRequest()
+
+		/**
+		 * @param sizeInBytes
+		 */
+		public void setSessionSize(long sizeInBytes)
 		{
-			if(currentRequest == null)
-			{
-				currentRequest = new RequestData();
-				requests.addFirst(currentRequest);
-				if(requests.size() > 1000)
-				{
-					requests.removeLast();
-				}
-			}
-			return currentRequest;
+			totalSessionSize = sizeInBytes;
 		}
 
-	}
-	
-	/**
-	 * This class hold the information one request of a session has.
-	 * 
-	 * @author jcompagner
-	 */
-	public static class RequestData implements Serializable
-	{
-		private static final long serialVersionUID = 1L;
-
-		private Date startDate;
-		private long timeTaken;
-		private List entries = new ArrayList(5);
-		private String eventTarget;
-		private String responseTarget;
-		
 		/**
-		 * @return The time taken for this request
+		 * @param id
 		 */
-		public Long getTimeTaken()
+		public void setSessionId(String id)
 		{
-			return new Long(timeTaken);
+			sessionId = id;
 		}
 
 		/**
@@ -551,7 +572,7 @@
 		 */
 		public Date getStartDate()
 		{
-			return startDate;
+			return new Date(startDate);
 		}
 
 		/**
@@ -592,7 +613,7 @@
 		public void setTimeTaken(long timeTaken)
 		{
 			this.timeTaken = timeTaken;
-			this.startDate = new Date(System.currentTimeMillis()-timeTaken);
+			this.startDate = System.currentTimeMillis()-timeTaken;
 		}
 
 		/**
@@ -619,6 +640,22 @@
 				}
 			}
 			return sb.toString();
+		}
+
+		/**
+		 * @return The session id for this request
+		 */
+		public String getSessionId()
+		{
+			return sessionId;
+		}
+
+		/**
+		 * @return The total session size.
+		 */
+		public Long getSessionSize()
+		{
+			return new Long(totalSessionSize);
 		}
 		
 	}

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WebApplication.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WebApplication.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WebApplication.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WebApplication.java Fri Nov 10 13:49:46 2006
@@ -21,6 +21,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
@@ -118,9 +119,6 @@
 	/** the default request cycle processor implementation. */
 	private IRequestCycleProcessor requestCycleProcessor;
 
-	/** Request logger instance. */
-	private RequestLogger requestLogger;
-
 	/**
 	 * the prefix for storing variables in the actual session (typically
 	 * {@link HttpSession} for this application instance.
@@ -173,15 +171,19 @@
 	}
 
 	/**
-	 * Gets the {@link RequestLogger}.
-	 * 
-	 * @return The RequestLogger
+	 * @return The Wicket servlet context for this application
 	 */
-	public final RequestLogger getRequestLogger()
+	public final ServletContext getServletContext()
 	{
-		return requestLogger;
+		if (wicketServlet == null)
+		{
+			throw new IllegalStateException("servletContext is not set yet. Any code in your"
+					+ " Application object that uses the wicketServlet instance should be put"
+					+ " in the init() method instead of your constructor");
+		}
+		return wicketServlet.getServletContext();
 	}
-
+	
 	/**
 	 * Gets the prefix for storing variables in the actual session (typically
 	 * {@link HttpSession} for this application instance.
@@ -227,7 +229,7 @@
 	public void logEventTarget(IRequestTarget target)
 	{
 		super.logEventTarget(target);
-		RequestLogger rl = getRequestLogger();
+		IRequestLogger rl = getRequestLogger();
 		if (rl != null)
 		{
 			rl.logEventTarget(target);
@@ -240,7 +242,7 @@
 	public void logResponseTarget(IRequestTarget target)
 	{
 		super.logResponseTarget(target);
-		RequestLogger rl = getRequestLogger();
+		IRequestLogger rl = getRequestLogger();
 		if (rl != null)
 		{
 			rl.logResponseTarget(target);
@@ -337,7 +339,7 @@
 	 * Create new Wicket Session object. Note, this method is not called if you
 	 * registered your own ISessionFactory with the Application.
 	 * 
-	 * @see wicket.ISessionFactory#newSession()
+	 * @return The created session 
 	 */
 	public Session newSession()
 	{
@@ -345,6 +347,14 @@
 	}
 
 	/**
+	 * @see wicket.ISessionFactory#newSession(wicket.Request)
+	 */
+	public Session newSession(Request request)
+	{
+		return newSession();
+	}
+	
+	/**
 	 * @param sessionId
 	 *            The session id that was destroyed
 	 */
@@ -352,7 +362,7 @@
 	{
 		bufferedResponses.remove(sessionId);
 
-		RequestLogger logger = getRequestLogger();
+		IRequestLogger logger = getRequestLogger();
 		if (logger != null)
 		{
 			logger.sessionDestroyed(sessionId);
@@ -360,17 +370,6 @@
 	}
 
 	/**
-	 * Sets the {@link RequestLogger}.
-	 * 
-	 * @param logger
-	 *            The request logger
-	 */
-	public final void setRequestLogger(RequestLogger logger)
-	{
-		requestLogger = logger;
-	}
-
-	/**
 	 * @param sessionFactory
 	 *            The session factory to use
 	 */
@@ -562,7 +561,7 @@
 	 */
 	protected ISessionStore newSessionStore()
 	{
-		return new HttpSessionStore();
+		return new SecondLevelCacheSessionStore(new FilePageStore());
 	}
 
 	/**
@@ -637,11 +636,11 @@
 		if (session == null)
 		{
 			// Create session using session factory
-			session = getSessionFactory().newSession();
+			session = getSessionFactory().newSession(request);
 			// Set the client Locale for this session
 			session.setLocale(request.getLocale());
 
-			if (sessionStore.getSessionId(request) != null)
+			if (sessionStore.getSessionId(request, false) != null)
 			{
 				// Bind the session to the session store
 				sessionStore.bind(request, session);
@@ -658,9 +657,6 @@
 			throw new WicketRuntimeException("Session created by a WebApplication session factory "
 					+ "must be a subclass of WebSession");
 		}
-
-		// Set application on session
-		session.setApplication(this);
 
 		// Set session attribute name and attach/reattach http servlet session
 		webSession.initForRequest();

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WicketServlet.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WicketServlet.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WicketServlet.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/WicketServlet.java Fri Nov 10 13:49:46 2006
@@ -139,10 +139,7 @@
 	public final void doGet(final HttpServletRequest servletRequest,
 			final HttpServletResponse servletResponse) throws ServletException, IOException
 	{
-		long time = System.currentTimeMillis();
-
-
-		// If the request does not provide information about the encoding of its
+		//	 If the request does not provide information about the encoding of its
 		// body (which includes POST parameters), than assume the default
 		// encoding as defined by the wicket application. Bear in mind that the
 		// encoding of the request usually is equal to the previous response.
@@ -176,7 +173,7 @@
 			{
 				// Try to see if there is a redirect stored
 				ISessionStore sessionStore = webApplication.getSessionStore();
-				String sessionId = sessionStore.getSessionId(request);
+				String sessionId = sessionStore.getSessionId(request,false);
 				BufferedHttpServletResponse bufferedResponse = webApplication.popBufferedResponse(
 						sessionId, queryString);
 
@@ -228,13 +225,6 @@
 			// Close response
 			response.close();
 
-			RequestLogger requestLogger = webApplication.getRequestLogger();
-
-			if (requestLogger != null)
-			{
-				requestLogger.requestTime((System.currentTimeMillis() - time));
-			}
-
 			// Clean up thread local session
 			Session.unset();
 
@@ -273,7 +263,6 @@
 
 			// Construct WebApplication subclass
 			this.webApplication = factory.createApplication(this);
-
 			// Finished
 			log.info("WicketServlet loaded application " + this.webApplication.getName() + " via "
 					+ factory.getClass().getName() + " factory");

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/portlet/PortletApplication.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/portlet/PortletApplication.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/portlet/PortletApplication.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/portlet/PortletApplication.java Fri Nov 10 13:49:46 2006
@@ -27,7 +27,7 @@
 import wicket.Session;
 import wicket.WicketRuntimeException;
 import wicket.markup.resolver.AutoLinkResolver;
-import wicket.protocol.http.RequestLogger;
+import wicket.protocol.http.IRequestLogger;
 import wicket.protocol.http.WebRequest;
 import wicket.protocol.http.WebRequestCycle;
 import wicket.protocol.http.WebResponse;
@@ -92,9 +92,6 @@
 	/** Session factory for this web application */
 	private ISessionFactory sessionFactory = this;
 
-	/** Request logger instance. */
-	private RequestLogger requestLogger;
-
 	private WicketPortlet portlet;
 
 	/**
@@ -133,7 +130,7 @@
 		if (session == null)
 		{
 			// Create session using session factory
-			session = getSessionFactory().newSession();
+			session = getSessionFactory().newSession(request);
 
 			// Set the client Locale for this session
 			session.setLocale(request.getLocale());
@@ -405,26 +402,6 @@
 		return requestCycleProcessor;
 	}
 
-	/**
-	 * Gets the {@link RequestLogger}.
-	 * 
-	 * @return The RequestLogger
-	 */
-	public final RequestLogger getRequestLogger()
-	{
-		return requestLogger;
-	}
-
-	/**
-	 * Sets the {@link RequestLogger}.
-	 * 
-	 * @param logger
-	 *            The request logger
-	 */
-	public final void setRequestLogger(RequestLogger logger)
-	{
-		requestLogger = logger;
-	}
 
 	/**
 	 * @param sessionId
@@ -432,7 +409,7 @@
 	 */
 	void sessionDestroyed(String sessionId)
 	{
-		RequestLogger logger = getRequestLogger();
+		IRequestLogger logger = getRequestLogger();
 		if (logger != null)
 		{
 			logger.sessionDestroyed(sessionId);

Modified: incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/request/WebClientInfo.java
URL: http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/request/WebClientInfo.java?view=diff&rev=473517&r1=473516&r2=473517
==============================================================================
--- incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/request/WebClientInfo.java (original)
+++ incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/request/WebClientInfo.java Fri Nov 10 13:49:46 2006
@@ -70,6 +70,7 @@
 		{
 			throw new WicketRuntimeException("unable to read header 'User-Agent'");
 		}
+		properties.setProperty(ClientProperties.REMOTE_ADDRESS,httpServletRequest.getRemoteAddr());
 		init();
 	}
 
@@ -91,7 +92,9 @@
 		}
 
 		this.userAgent = userAgent;
-
+		HttpServletRequest httpServletRequest = requestCycle.getWebRequest()
+		.getHttpServletRequest();
+		properties.setProperty(ClientProperties.REMOTE_ADDRESS,httpServletRequest.getRemoteAddr());
 		init();
 	}