001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.protocol.http; 018 019import org.apache.wicket.request.ILoggableRequestHandler; 020import org.apache.wicket.request.IRequestHandler; 021import org.apache.wicket.util.lang.Classes; 022import org.apache.wicket.util.string.Strings; 023import org.slf4j.Logger; 024import org.slf4j.LoggerFactory; 025 026/** 027 * This is the logger class that can be set in the 028 * {@link org.apache.wicket.protocol.http.WebApplication#getRequestLogger()} method. If this class 029 * is set all request and live sessions will be recorded and displayed From the total created 030 * sessions, to the peak session count and the current live sessions. For the live sessions the 031 * request logger will record what request are happening what kind of {@link IRequestHandler} was 032 * the event target and what {@link IRequestHandler} was the response target. It also records what 033 * session data was touched for this and how long the request did take. 034 * 035 * To view this information live see org.apache.wicket.devutils.inspector.InspectorBug that shows 036 * the org.apache.wicket.devutils.inspector.InspectorPage with the org.apache.wicket.devutils.inspector.LiveSessionsPage. 037 * 038 * This implementation uses a rounded buffer for storing the request data, and strives to minimize 039 * contention on accessing the rounded buffer. At the beginning of your application start, the 040 * buffer is empty and fills up during the lifetime of the application until the window size has 041 * been reached, and new requests are written to the position containing the oldest request. 042 * 043 * @since 1.2 044 */ 045public class RequestLogger extends AbstractRequestLogger 046{ 047 /** log, don't change this as it is often used to direct request logging to a different file. */ 048 private static final Logger LOG = LoggerFactory.getLogger(RequestLogger.class); 049 050 @Override 051 protected void log(RequestData rd, SessionData sd) 052 { 053 if (LOG.isInfoEnabled()) 054 { 055 LOG.info(createRequestData(rd, sd)); 056 } 057 } 058 059 private String createRequestData(RequestData rd, SessionData sd) 060 { 061 StringBuilder sb = new StringBuilder(768); 062 063 sb.append("startTime=\""); 064 sb.append(formatDate(rd.getStartDate())); 065 sb.append("\",duration="); 066 sb.append(rd.getTimeTaken()); 067 sb.append(",url=\""); 068 sb.append(rd.getRequestedUrl()); 069 sb.append('"'); 070 sb.append(",event={"); 071 appendRequestHandlerString(sb, rd.getEventTarget()); 072 sb.append("},response={"); 073 appendRequestHandlerString(sb, rd.getResponseTarget()); 074 sb.append("},sessionid=\""); 075 sb.append(rd.getSessionId()); 076 sb.append('"'); 077 sb.append(",sessionsize="); 078 sb.append(rd.getSessionSize()); 079 if (rd.getSessionInfo() != null && !Strings.isEmpty(rd.getSessionInfo().toString())) 080 { 081 sb.append(",sessioninfo={"); 082 sb.append(rd.getSessionInfo()); 083 sb.append('}'); 084 } 085 if (sd != null) 086 { 087 sb.append(",sessionstart=\""); 088 sb.append(formatDate(sd.getStartDate())); 089 sb.append("\",requests="); 090 sb.append(sd.getNumberOfRequests()); 091 sb.append(",totaltime="); 092 sb.append(sd.getTotalTimeTaken()); 093 } 094 sb.append(",activerequests="); 095 sb.append(rd.getActiveRequest()); 096 097 Runtime runtime = Runtime.getRuntime(); 098 long max = runtime.maxMemory() / 1000000; 099 long total = runtime.totalMemory() / 1000000; 100 long used = total - runtime.freeMemory() / 1000000; 101 sb.append(",maxmem="); 102 sb.append(max); 103 sb.append("M,total="); 104 sb.append(total); 105 sb.append("M,used="); 106 sb.append(used); 107 sb.append('M'); 108 109 return sb.toString(); 110 } 111 112 private void appendRequestHandlerString(StringBuilder sb, IRequestHandler handler) 113 { 114 if (handler != null) 115 { 116 Class<? extends IRequestHandler> handlerClass = handler.getClass(); 117 sb.append("handler="); 118 sb.append(handlerClass.isAnonymousClass() ? handlerClass.getName() 119 : Classes.simpleName(handlerClass)); 120 if (handler instanceof ILoggableRequestHandler) 121 { 122 sb.append(",data="); 123 sb.append(((ILoggableRequestHandler)handler).getLogData()); 124 } 125 } 126 else 127 { 128 sb.append("none"); 129 } 130 } 131}