/*
* 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 org.apache.wicket.request.ILogData;
import org.apache.wicket.request.ILoggableRequestHandler;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.handler.logger.NoLogData;
import org.apache.wicket.session.ISessionStore;
import org.apache.wicket.util.io.IClusterable;
import org.apache.wicket.util.string.Strings;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Interface for the request logger and viewer.
*
* @see org.apache.wicket.Application#newRequestLogger()
*
* @author jcompagner
*/
public interface IRequestLogger
{
/**
* @return The total created sessions counter
*/
int getTotalCreatedSessions();
/**
* @return The peak sessions counter
*/
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
*/
List<RequestData> getRequests();
/**
* @return Collection of live Sessions Data
*/
SessionData[] getLiveSessions();
/**
* @return The current active requests
*/
int getCurrentActiveRequestCount();
/**
* @return The {@link org.apache.wicket.protocol.http.IRequestLogger.RequestData} for the current request.
*/
RequestData getCurrentRequest();
/**
* @return The peak active requests
*/
int getPeakActiveRequestCount();
/**
* @return The number of requests per minute.
*/
long getRequestsPerMinute();
/**
* @return The average request time.
*/
long getAverageRequestTime();
/**
* called when the session is created and has an id. (for http it means that the http session is
* created)
*
* @param id
* the session id
*/
void sessionCreated(String id);
/**
* Method used to cleanup a livesession when the session was invalidated by the webcontainer
*
* @param sessionId
* the session id
*/
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
* the time taken in milliseconds
*/
void requestTime(long timeTaken);
/**
* Called to monitor removals of objects out of the {@link ISessionStore}
*
* @param value
* the object being removed
*/
void objectRemoved(Object value);
/**
* Called to monitor updates of objects in the {@link ISessionStore}
*
* @param value
* the object being updated
*/
void objectUpdated(Object value);
/**
* Called to monitor additions of objects in the {@link ISessionStore}
*
* @param value
* the object being created/added
*/
void objectCreated(Object value);
/**
* Sets the target that was the response target for the current request
*
* @param target
* the response target
*/
void logResponseTarget(IRequestHandler target);
/**
* Sets the target that was the event target for the current request
*
* @param target
* the event target
*/
void logEventTarget(IRequestHandler target);
/**
* Logs the URL that was requested by the browser.
*
* @param url
* the requested URL
*/
void logRequestedUrl(String url);
/**
* Perform the actual logging
*/
void performLogging();
/**
* This class hold the information one request of a session has.
*
* @author jcompagner
*/
class SessionData implements IClusterable, Comparable<SessionData>
{
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 in ms.
*/
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;
}
/**
* Adds {@code time} to the total server time.
*
* @param time
*/
public void addTimeTaken(long time)
{
lastActive = System.currentTimeMillis();
numberOfRequests++;
totalTimeTaken += time;
}
/**
* Sets additional session info (e.g. logged in user).
*
* @param sessionInfo
*/
public void setSessionInfo(Object sessionInfo)
{
this.sessionInfo = sessionInfo;
}
/**
* Sets the recorded session size.
*
* @param size
*/
public void setSessionSize(long size)
{
sessionSize = size;
}
@Override
public int compareTo(SessionData sd)
{
if (sd.startDate > startDate)
{
return 1;
}
else if (sd.startDate < startDate)
{
return -1;
}
return 0;
}
}
/**
* This class hold the information one request of a session has.
*
* @author jcompagner
*/
class RequestData implements IClusterable
{
private static final long serialVersionUID = 1L;
private long startDate;
private long timeTaken;
private final List<String> entries = new ArrayList<>(5);
private Map<String, Object> userData;
private String requestedUrl;
private IRequestHandler eventTarget;
private IRequestHandler responseTarget;
private String sessionId;
private long totalSessionSize;
private Object sessionInfo;
private int activeRequest;
/**
* @return The time taken for this request
*/
public Long getTimeTaken()
{
return timeTaken;
}
/**
* @param activeRequest
* The number of active request when this request happened
*/
public void setActiveRequest(int activeRequest)
{
this.activeRequest = activeRequest;
}
/**
* @return The number of active request when this request happened
*/
public int getActiveRequest()
{
return activeRequest;
}
/**
* @return The session object info, created by {@link ISessionLogInfo#getSessionInfo()}
*/
public Object getSessionInfo()
{
return sessionInfo;
}
/**
* Set the session info object of the session for this request.
*
* @param sessionInfo
*/
public void setSessionInfo(Object sessionInfo)
{
this.sessionInfo = sessionInfo;
}
/**
* @param sizeInBytes
*/
public void setSessionSize(long sizeInBytes)
{
totalSessionSize = sizeInBytes;
}
/**
* @param id
*/
public void setSessionId(String id)
{
sessionId = id;
}
/**
* @return The time taken for this request
*/
public Date getStartDate()
{
return new Date(startDate);
}
/**
* @return The event target
*/
public IRequestHandler getEventTarget()
{
return eventTarget;
}
/**
* @return The class of the event target
*/
public Class<? extends IRequestHandler> getEventTargetClass()
{
return eventTarget == null ? null : eventTarget.getClass();
}
/**
* @return The log data for the eventTarget, or {@link NoLogData} if the request handler is
* not loggable
*/
public ILogData getEventTargetLog()
{
if (eventTarget instanceof ILoggableRequestHandler)
return ((ILoggableRequestHandler)eventTarget).getLogData();
return new NoLogData();
}
/**
* @return The response target
*/
public IRequestHandler getResponseTarget()
{
return responseTarget;
}
/**
* @return The class of the response target
*/
public Class<? extends IRequestHandler> getResponseTargetClass()
{
return responseTarget == null ? null : responseTarget.getClass();
}
/**
* @return The log data for the responseTarget, or {@link NoLogData} if the request handler
* is not loggable
*/
public ILogData getResponseTargetLog()
{
if (responseTarget instanceof ILoggableRequestHandler)
return ((ILoggableRequestHandler)responseTarget).getLogData();
return new NoLogData();
}
/**
* @return the requested URL by the browser
*/
public String getRequestedUrl()
{
return requestedUrl;
}
/**
* @param requestedUrl
*/
public void setRequestedUrl(String requestedUrl)
{
this.requestedUrl = requestedUrl;
}
/**
* @param target
*/
public void setResponseTarget(IRequestHandler target)
{
responseTarget = target;
}
/**
* @param target
*/
public void setEventTarget(IRequestHandler target)
{
eventTarget = target;
}
/**
* @param timeTaken
*/
public void setTimeTaken(long timeTaken)
{
this.timeTaken = timeTaken;
startDate = System.currentTimeMillis() - timeTaken;
}
/**
* @param string
*/
public void addEntry(String string)
{
entries.add(string);
}
/**
* @param key
* @param value
*/
public void addUserData(String key, Object value)
{
getUserData().put(key, value);
}
/**
* @param key
* @return
*/
public Object getUserData(String key)
{
return getUserData().get(key);
}
/**
* @return the userData Map
*/
public Map<String, Object> getUserData()
{
if (userData == null) {
userData = new HashMap<>();
}
return userData;
}
/**
* @return All entries of the objects that are created/updated or removed in this request
*/
public String getAlteredObjects()
{
return Strings.join(", ", entries);
}
/**
* @return The session id for this request
*/
public String getSessionId()
{
return sessionId;
}
/**
* @return The total session size.
*/
public Long getSessionSize()
{
return totalSessionSize;
}
@Override
public String toString()
{
return "Request[timetaken=" + getTimeTaken() + ",sessioninfo=" + sessionInfo +
",sessionid=" + sessionId + ",sessionsize=" + totalSessionSize + ",request=" +
eventTarget + ",response=" + responseTarget + ",alteredobjects=" +
getAlteredObjects() + ",activerequest=" + activeRequest + "]";
}
}
/**
* 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
*/
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();
}
}