org.apache.wicket.protocol.http.RequestLogger Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.ops4j.pax.wicket.service Show documentation
Show all versions of org.ops4j.pax.wicket.service Show documentation
Pax Wicket Service is an OSGi extension of the Wicket framework, allowing for dynamic loading and
unloading of Wicket components and pageSources.
/*
* 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.protocol.http;
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 java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.wicket.Application;
import org.apache.wicket.IClusterable;
import org.apache.wicket.IPageMap;
import org.apache.wicket.IRequestTarget;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.Page;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.Session;
import org.apache.wicket.request.target.component.IBookmarkablePageRequestTarget;
import org.apache.wicket.request.target.component.IPageRequestTarget;
import org.apache.wicket.request.target.component.listener.IListenerInterfaceRequestTarget;
import org.apache.wicket.request.target.resource.ISharedResourceRequestTarget;
import org.apache.wicket.util.lang.Classes;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This is the logger class that can be set in the
* {@link org.apache.wicket.protocol.http.WebApplication#getRequestLogger()} method. If this class
* is set all request and live sessions will be recorded and displayed From the total created
* sessions, to the peak session count and the current livesessions. For the livesessions the
* request logger will record what request are happening what kind of {@link IRequestTarget} was the
* event target and what {@link IRequestTarget} was the response target. It also records what
* session data was touched for this and how long the request did take.
*
* To view this information live see the {@link InspectorBug} that shows the {@link InspectorPage}
* with the {@link LiveSessionsPage}
*
* @author jcompagner
*
* @since 1.2
*/
public class RequestLogger implements IRequestLogger
{
/** log. */
protected static Logger log = LoggerFactory.getLogger(RequestLogger.class);
private static MetaDataKey REQUEST_DATA = new MetaDataKey()
{
private static final long serialVersionUID = 1L;
};
/**
* 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
{
/**
* If you use the request logger log functionality then this object should have a nice
* String representation. So make sure that the toString() is implemented for the returned
* object.
*
* @return The custom object stored in the request loggers current request.
*/
Object getSessionInfo();
}
private final AtomicInteger totalCreatedSessions = new AtomicInteger();
private final AtomicInteger peakSessions = new AtomicInteger();
private final List requests;
private final Map liveSessions;
private final AtomicInteger active = new AtomicInteger();
private final AtomicInteger peakActive = new AtomicInteger();
/**
* Construct.
*/
public RequestLogger()
{
requests = Collections.synchronizedList(new LinkedList()
{
private static final long serialVersionUID = 1L;
/**
* @see java.util.LinkedList#add(java.lang.Object)
*/
@Override
public void add(int index, RequestData o)
{
super.add(index, o);
if (size() > Application.get().getRequestLoggerSettings().getRequestsWindowSize())
{
removeLast();
}
}
});
liveSessions = new ConcurrentHashMap();
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#getTotalCreatedSessions()
*/
public int getTotalCreatedSessions()
{
return totalCreatedSessions.get();
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#getPeakSessions()
*/
public int getPeakSessions()
{
return peakSessions.get();
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#getCurrentActiveRequestCount()
*/
public int getCurrentActiveRequestCount()
{
return active.get();
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#getPeakActiveRequestCount()
*/
public int getPeakActiveRequestCount()
{
return peakActive.get();
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#getRequests()
*/
public List getRequests()
{
return Collections.unmodifiableList(requests);
}
public SessionData[] getLiveSessions()
{
SessionData[] sessions = liveSessions.values().toArray(
new SessionData[liveSessions.values().size()]);
Arrays.sort(sessions);
return sessions;
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#sessionDestroyed(java.lang.String)
*/
public void sessionDestroyed(String sessionId)
{
liveSessions.remove(sessionId);
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#sessionDestroyed(java.lang.String)
*/
public void sessionCreated(String sessionId)
{
liveSessions.put(sessionId, new SessionData(sessionId));
if (liveSessions.size() > peakSessions.get())
{
peakSessions.set(liveSessions.size());
}
totalCreatedSessions.incrementAndGet();
}
RequestData getCurrentRequest()
{
RequestCycle requestCycle = RequestCycle.get();
RequestData rd = requestCycle.getMetaData(REQUEST_DATA);
if (rd == null)
{
rd = new RequestData();
requestCycle.setMetaData(REQUEST_DATA, rd);
int activeCount = active.incrementAndGet();
if (activeCount > peakActive.get())
{
peakActive.set(activeCount);
}
}
return rd;
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#requestTime(long)
*/
public void requestTime(long timeTaken)
{
RequestData rd = RequestCycle.get().getMetaData(REQUEST_DATA);
if (rd != null)
{
if (active.get() > 0)
{
rd.setActiveRequest(active.decrementAndGet());
}
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())
{
try
{
sizeInBytes = session.getSizeInBytes();
}
catch (Exception e)
{
// log the error and let the request logging continue (this is what happens in
// the
// detach phase of the request cycle anyway. This provides better diagnostics).
log.error(
"Exception while determining the size of the session in the request logger: " +
e.getMessage(), e);
}
}
rd.setSessionSize(sizeInBytes);
rd.setTimeTaken(timeTaken);
requests.add(0, rd);
if (sessionId != null)
{
SessionData sd = liveSessions.get(sessionId);
if (sd == null && session.isSessionInvalidated() == false)
{
// passivated session or logger only started after it.
sessionCreated(sessionId);
sd = liveSessions.get(sessionId);
}
if (sd != null)
{
sd.setSessionInfo(sessionInfo);
sd.setSessionSize(sizeInBytes);
sd.addTimeTaken(timeTaken);
log(rd, sd);
}
else
{
log(rd, null);
}
}
else
{
log(rd, null);
}
}
}
/**
* @param rd
* @param sd
*/
protected void log(RequestData rd, SessionData sd)
{
if (log.isInfoEnabled())
{
log.info(createLogString(rd, sd, true).toString());
}
}
protected AppendingStringBuffer createLogString(RequestData rd, SessionData sd,
boolean includeRuntimeInfo)
{
AppendingStringBuffer asb = new AppendingStringBuffer(150);
asb.append("time=");
asb.append(rd.getTimeTaken());
asb.append(",event=");
asb.append(rd.getEventTarget());
asb.append(",response=");
asb.append(rd.getResponseTarget());
if (rd.getSessionInfo() != null && !rd.getSessionInfo().equals(""))
{
asb.append(",sessioninfo=");
asb.append(rd.getSessionInfo());
}
else
{
asb.append(",sessionid=");
asb.append(rd.getSessionId());
}
asb.append(",sessionsize=");
asb.append(rd.getSessionSize());
if (sd != null)
{
asb.append(",sessionstart=");
asb.append(sd.getStartDate());
asb.append(",requests=");
asb.append(sd.getNumberOfRequests());
asb.append(",totaltime=");
asb.append(sd.getTotalTimeTaken());
}
asb.append(",activerequests=");
asb.append(rd.getActiveRequest());
if (includeRuntimeInfo)
{
Runtime runtime = Runtime.getRuntime();
long max = runtime.maxMemory() / 1000000;
long total = runtime.totalMemory() / 1000000;
long used = total - runtime.freeMemory() / 1000000;
asb.append(",maxmem=");
asb.append(max);
asb.append("M,total=");
asb.append(total);
asb.append("M,used=");
asb.append(used);
asb.append("M");
}
return asb;
}
private Object getSessionInfo(Session session)
{
if (session instanceof ISessionLogInfo)
{
return ((ISessionLogInfo)session).getSessionInfo();
}
return "";
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#objectRemoved(java.lang.Object)
*/
public void objectRemoved(Object value)
{
RequestData rd = getCurrentRequest();
if (value instanceof Page)
{
Page page = (Page)value;
rd.addEntry("Page removed, id: " + page.getId() + ", class:" + page.getClass());
}
else if (value instanceof IPageMap)
{
IPageMap map = (IPageMap)value;
rd.addEntry("PageMap removed, name: " +
(map.getName() == null ? "DEFAULT" : map.getName()));
}
else if (value instanceof WebSession)
{
rd.addEntry("Session removed");
}
else
{
rd.addEntry("Custom object removed: " + value);
}
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#objectUpdated(java.lang.Object)
*/
public void objectUpdated(Object value)
{
RequestData rd = getCurrentRequest();
if (value instanceof Page)
{
Page page = (Page)value;
rd.addEntry("Page updated, id: " + page.getId() + ", class:" + page.getClass());
}
else if (value instanceof IPageMap)
{
IPageMap map = (IPageMap)value;
rd.addEntry("PageMap updated, name: " +
(map.getName() == null ? "DEFAULT" : map.getName()));
}
else if (value instanceof Session)
{
rd.addEntry("Session updated");
}
else
{
rd.addEntry("Custom object updated: " + value);
}
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#objectCreated(java.lang.Object)
*/
public void objectCreated(Object value)
{
RequestData rd = getCurrentRequest();
if (value instanceof Session)
{
rd.addEntry("Session created");
}
else if (value instanceof Page)
{
Page page = (Page)value;
rd.addEntry("Page created, id: " + page.getId() + ", class:" + page.getClass());
}
else if (value instanceof IPageMap)
{
IPageMap map = (IPageMap)value;
rd.addEntry("PageMap created, name: " +
(map.getName() == null ? "DEFAULT" : map.getName()));
}
else
{
rd.addEntry("Custom object created: " + value);
}
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#logResponseTarget(org.apache.wicket.IRequestTarget)
*/
public void logResponseTarget(IRequestTarget target)
{
getCurrentRequest().addResponseTarget(getRequestTargetString(target));
}
/**
* @see org.apache.wicket.protocol.http.IRequestLogger#logEventTarget(org.apache.wicket.IRequestTarget)
*/
public void logEventTarget(IRequestTarget target)
{
getCurrentRequest().addEventTarget(getRequestTargetString(target));
}
/**
* @param target
* @return The request target nice display string
*/
private String getRequestTargetString(IRequestTarget target)
{
AppendingStringBuffer sb = new AppendingStringBuffer(128);
if (target instanceof IListenerInterfaceRequestTarget)
{
IListenerInterfaceRequestTarget listener = (IListenerInterfaceRequestTarget)target;
sb.append("Interface[target:");
sb.append(Classes.simpleName(listener.getTarget().getClass()));
sb.append("(");
sb.append(listener.getTarget().getPageRelativePath());
sb.append("), page: ");
sb.append(listener.getPage().getClass().getName());
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[");
sb.append(pageRequestTarget.getPage().getClass().getName());
sb.append("(");
sb.append(pageRequestTarget.getPage().getId());
sb.append(")]");
}
else if (target instanceof IBookmarkablePageRequestTarget)
{
IBookmarkablePageRequestTarget pageRequestTarget = (IBookmarkablePageRequestTarget)target;
sb.append("BookmarkablePage[");
sb.append(pageRequestTarget.getPageClass().getName());
sb.append("(").append(pageRequestTarget.getPageParameters()).append(")");
sb.append("]");
}
else if (target instanceof ISharedResourceRequestTarget)
{
ISharedResourceRequestTarget sharedResourceTarget = (ISharedResourceRequestTarget)target;
sb.append("SharedResource[");
sb.append(sharedResourceTarget.getResourceKey());
sb.append("]");
}
else
{
sb.append(target.toString());
}
return sb.toString();
}
/**
* This class hold the information one request of a session has.
*
* @author jcompagner
*/
public static class SessionData implements IClusterable, Comparable
{
private static final long serialVersionUID = 1L;
private final String sessionId;
private final long startDate;
private long lastActive;
private long numberOfRequests;
private long totalTimeTaken;
private long sessionSize;
private Object sessionInfo;
/**
* Construct.
*
* @param sessionId
*/
public SessionData(String sessionId)
{
this.sessionId = sessionId;
startDate = System.currentTimeMillis();
numberOfRequests = 1;
}
/**
* @return The last active date.
*/
public Date getLastActive()
{
return new Date(lastActive);
}
/**
* @return The start date of this session
*/
public Date getStartDate()
{
return new Date(startDate);
}
/**
* @return The number of request for this session
*/
public long getNumberOfRequests()
{
return numberOfRequests;
}
/**
* @return Returns the session size.
*/
public long getSessionSize()
{
return sessionSize;
}
/**
* @return Returns the total time this session has spent.
*/
public long getTotalTimeTaken()
{
return totalTimeTaken;
}
/**
* @return The session info object given by the {@link ISessionLogInfo#getSessionInfo()}
* session method.
*/
public Object getSessionInfo()
{
return sessionInfo;
}
/**
* @return The session id
*/
public String getSessionId()
{
return sessionId;
}
public void addTimeTaken(long time)
{
lastActive = System.currentTimeMillis();
numberOfRequests++;
totalTimeTaken += time;
}
public void setSessionInfo(Object sessionInfo)
{
this.sessionInfo = sessionInfo;
}
public void setSessionSize(long size)
{
sessionSize = size;
}
public int compareTo(SessionData sd)
{
return (int)(sd.lastActive - lastActive);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy