/* * 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(); } }