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 jakarta.servlet.http.HttpServletRequest; 020 021import org.apache.wicket.Application; 022import org.apache.wicket.request.IRequestHandler; 023import org.apache.wicket.request.cycle.IRequestCycleListener; 024import org.apache.wicket.request.cycle.RequestCycle; 025import org.apache.wicket.settings.RequestLoggerSettings; 026import org.apache.wicket.util.string.AppendingStringBuffer; 027 028/** 029 * Listener that logs request details in the {@link Application#getRequestLogger()} request logger. 030 */ 031public class RequestLoggerRequestCycleListener implements IRequestCycleListener 032{ 033 /** 034 * Listeners are not thread safe. In order to keep track if a handler was the first in the 035 * request cycle, register a {@code ThreadLocal} that gets cleared out at the 036 * {@link #onEndRequest(RequestCycle) end of the request} 037 */ 038 private static final ThreadLocal<IRequestHandler> first = new ThreadLocal<IRequestHandler>(); 039 040 @Override 041 public void onBeginRequest(RequestCycle cycle) 042 { 043 if (!isRequestLoggingEnabled()) 044 return; 045 046 registerRequestedUrl(cycle); 047 } 048 049 @Override 050 public void onRequestHandlerScheduled(RequestCycle cycle, IRequestHandler handler) 051 { 052 if (!isRequestLoggingEnabled()) 053 return; 054 055 registerHandler(handler); 056 } 057 058 @Override 059 public void onRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler) 060 { 061 if (!isRequestLoggingEnabled()) 062 return; 063 064 registerHandler(handler); 065 } 066 067 @Override 068 public void onExceptionRequestHandlerResolved(RequestCycle cycle, IRequestHandler handler, 069 Exception exception) 070 { 071 if (!isRequestLoggingEnabled()) 072 return; 073 074 registerHandler(handler); 075 } 076 077 @Override 078 public void onEndRequest(RequestCycle cycle) 079 { 080 first.remove(); 081 } 082 083 /** 084 * Determine whether a IRequestLogger is provided, and whether request logging has been enabled. 085 * 086 * @return true when request logging is enabled. 087 */ 088 private boolean isRequestLoggingEnabled() 089 { 090 IRequestLogger requestLogger = Application.get().getRequestLogger(); 091 RequestLoggerSettings settings = Application.get().getRequestLoggerSettings(); 092 return requestLogger != null && settings.isRequestLoggerEnabled(); 093 } 094 095 /** 096 * Registers the requested URL with the request logger, if one can be determined. 097 * 098 * @param cycle 099 */ 100 private void registerRequestedUrl(RequestCycle cycle) 101 { 102 IRequestLogger requestLogger = Application.get().getRequestLogger(); 103 if (cycle.getRequest().getContainerRequest() instanceof HttpServletRequest) 104 { 105 HttpServletRequest containerRequest = (HttpServletRequest)cycle.getRequest() 106 .getContainerRequest(); 107 108 AppendingStringBuffer url = new AppendingStringBuffer(containerRequest.getRequestURL()); 109 if (containerRequest.getQueryString() != null) 110 url.append("?").append(containerRequest.getQueryString()); 111 112 requestLogger.logRequestedUrl(url.toString()); 113 } 114 } 115 116 /** 117 * Registers the handler with the request logger. The first handler is used as the incoming 118 * request handler, and the last registered handler as the outgoing response handler. 119 * 120 * @param handler 121 */ 122 private void registerHandler(IRequestHandler handler) 123 { 124 IRequestLogger requestLogger = Application.get().getRequestLogger(); 125 126 if (first.get() == null) 127 { 128 first.set(handler); 129 requestLogger.logEventTarget(handler); 130 } 131 requestLogger.logResponseTarget(handler); 132 } 133}