On 18/08/2009, ma...@apache.org <ma...@apache.org> wrote: > Author: markt > Date: Tue Aug 18 11:49:26 2009 > New Revision: 805375 > > URL: http://svn.apache.org/viewvc?rev=805375&view=rev > Log: > Replace the RequestDumperValve with a RequestDumperFilter. Merge the > RequestDumperFilter from the examples with this new filter. > Adds: > - thread name to start of output line to make analysing output easier > - request timings > GSOC 2009 > Based on a patch by Xie Xiaodong > > Added: > tomcat/trunk/java/org/apache/catalina/filters/RequestDumperFilter.java > (with props) > Removed: > tomcat/trunk/java/org/apache/catalina/valves/RequestDumperValve.java > > tomcat/trunk/webapps/examples/WEB-INF/classes/filters/RequestDumperFilter.java > Modified: > tomcat/trunk/conf/server.xml > tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java > tomcat/trunk/webapps/docs/config/filter.xml > tomcat/trunk/webapps/docs/config/valve.xml > tomcat/trunk/webapps/examples/WEB-INF/web.xml > > Modified: tomcat/trunk/conf/server.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/conf/server.xml?rev=805375&r1=805374&r2=805375&view=diff > > ============================================================================== > --- tomcat/trunk/conf/server.xml (original) > +++ tomcat/trunk/conf/server.xml Tue Aug 18 11:49:26 2009 > @@ -106,13 +106,6 @@ > <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> > --> > > - <!-- The request dumper valve dumps useful debugging information about > - the request and response data received and sent by Tomcat. > - Documentation at: /docs/config/valve.html --> > - <!-- > - <Valve className="org.apache.catalina.valves.RequestDumperValve"/> > - --> > - > <!-- This Realm uses the UserDatabase configured in the global JNDI > resources under the key "UserDatabase". Any edits > that are performed against this UserDatabase are immediately > > Added: tomcat/trunk/java/org/apache/catalina/filters/RequestDumperFilter.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/filters/RequestDumperFilter.java?rev=805375&view=auto > > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/filters/RequestDumperFilter.java > (added) > +++ tomcat/trunk/java/org/apache/catalina/filters/RequestDumperFilter.java > Tue Aug 18 11:49:26 2009 > @@ -0,0 +1,283 @@ > +/* > + * 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.catalina.filters; > + > +import java.io.IOException; > +import java.text.SimpleDateFormat; > +import java.util.Date; > +import java.util.Enumeration; > + > +import javax.servlet.Filter; > +import javax.servlet.FilterChain; > +import javax.servlet.FilterConfig; > +import javax.servlet.ServletException; > +import javax.servlet.ServletRequest; > +import javax.servlet.ServletResponse; > +import javax.servlet.http.Cookie; > +import javax.servlet.http.HttpServletRequest; > +import javax.servlet.http.HttpServletResponse; > + > +import org.apache.juli.logging.Log; > +import org.apache.juli.logging.LogFactory; > + > + > +/** > + * <p>Implementation of a Filter that logs interesting contents from the > + * specified Request (before processing) and the corresponding Response > + * (after processing). It is especially useful in debugging problems > + * related to headers and cookies.</p> > + * > + * <p>When using this Filter, it is strongly recommended that the > + * <code>org.apache.catalina.filter.RequestDumperFilter</code> logger is > + * directed to a dedicated file and that the > + * <code>org.apache.juli.VerbatimFormmater</code> is used.</p> > + * > + * @author Craig R. McClanahan
Was the author really Craig? If not, I suggest that the annotation is removed. > + */ > + > +public class RequestDumperFilter implements Filter { > + > + private static final String NON_HTTP_REQ_MSG = > + "Not available. Non-http request."; > + private static final String NON_HTTP_RES_MSG = > + "Not available. Non-http response."; > + > + private static final ThreadLocal<Timestamp> timestamp = > + new ThreadLocal<Timestamp>() { > + protected Timestamp initialValue() { > + return new Timestamp(); > + } > + }; > + > + /** > + * The logger for this class. > + */ > + private static Log log = LogFactory.getLog(RequestDumperFilter.class); > + > + > + /** > + * Log the interesting request parameters, invoke the next Filter in the > + * sequence, and log the interesting response parameters. > + * > + * @param request The servlet request to be processed > + * @param response The servlet response to be created > + * @param chain The filter chain being processed > + * > + * @exception IOException if an input/output error occurs > + * @exception ServletException if a servlet error occurs > + */ > + public void doFilter(ServletRequest request, ServletResponse response, > + FilterChain chain) > + throws IOException, ServletException { > + > + HttpServletRequest hRequest = null; > + HttpServletResponse hResponse = null; > + > + if (request instanceof HttpServletRequest) { > + hRequest = (HttpServletRequest) request; > + } > + if (response instanceof HttpServletResponse) { > + hResponse = (HttpServletResponse) response; > + } > + > + // Log pre-service information > + doLog("START TIME ", getTimestamp()); > + > + if (hRequest == null) { > + doLog(" requestURI", NON_HTTP_REQ_MSG); > + doLog(" authType", NON_HTTP_REQ_MSG); > + } else { > + doLog(" requestURI", hRequest.getRequestURI()); > + doLog(" authType", hRequest.getAuthType()); > + } > + > + doLog(" characterEncoding", request.getCharacterEncoding()); > + doLog(" contentLength", > + Integer.valueOf(request.getContentLength()).toString()); > + doLog(" contentType", request.getContentType()); > + > + if (hRequest == null) { > + doLog(" contextPath", NON_HTTP_REQ_MSG); > + doLog(" cookie", NON_HTTP_REQ_MSG); > + doLog(" header", NON_HTTP_REQ_MSG); > + } else { > + doLog(" contextPath", hRequest.getContextPath()); > + Cookie cookies[] = hRequest.getCookies(); > + if (cookies != null) { > + for (int i = 0; i < cookies.length; i++) > + doLog(" cookie", cookies[i].getName() + > + "=" + cookies[i].getValue()); > + } > + Enumeration<String> hnames = hRequest.getHeaderNames(); > + while (hnames.hasMoreElements()) { > + String hname = hnames.nextElement(); > + Enumeration<String> hvalues = hRequest.getHeaders(hname); > + while (hvalues.hasMoreElements()) { > + String hvalue = hvalues.nextElement(); > + doLog(" header", hname + "=" + hvalue); > + } > + } > + } > + > + doLog(" locale", request.getLocale().toString()); > + > + if (hRequest == null) { > + doLog(" method", NON_HTTP_REQ_MSG); > + } else { > + doLog(" method", hRequest.getMethod()); > + } > + > + Enumeration<String> pnames = request.getParameterNames(); > + while (pnames.hasMoreElements()) { > + String pname = pnames.nextElement(); > + String pvalues[] = request.getParameterValues(pname); > + StringBuffer result = new StringBuffer(pname); > + result.append('='); > + for (int i = 0; i < pvalues.length; i++) { > + if (i > 0) > + result.append(", "); > + result.append(pvalues[i]); > + } > + doLog(" parameter", result.toString()); > + } > + > + if (hRequest == null) { > + doLog(" pathInfo", NON_HTTP_REQ_MSG); > + } else { > + doLog(" pathInfo", hRequest.getPathInfo()); > + } > + > + doLog(" protocol", request.getProtocol()); > + > + if (hRequest == null) { > + doLog(" queryString", NON_HTTP_REQ_MSG); > + } else { > + doLog(" queryString", hRequest.getQueryString()); > + } > + > + doLog(" remoteAddr", request.getRemoteAddr()); > + doLog(" remoteHost", request.getRemoteHost()); > + > + if (hRequest == null) { > + doLog(" remoteUser", NON_HTTP_REQ_MSG); > + doLog("requestedSessionId", NON_HTTP_REQ_MSG); > + } else { > + doLog(" remoteUser", hRequest.getRemoteUser()); > + doLog("requestedSessionId", hRequest.getRequestedSessionId()); > + } > + > + doLog(" scheme", request.getScheme()); > + doLog(" serverName", request.getServerName()); > + doLog(" serverPort", > + Integer.valueOf(request.getServerPort()).toString()); > + > + if (hRequest == null) { > + doLog(" servletPath", NON_HTTP_REQ_MSG); > + } else { > + doLog(" servletPath", hRequest.getServletPath()); > + } > + > + doLog(" isSecure", > + Boolean.valueOf(request.isSecure()).toString()); > + doLog("------------------", > + "--------------------------------------------"); > + > + // Perform the request > + chain.doFilter(request, response); > + > + // Log post-service information > + doLog("------------------", > + "--------------------------------------------"); > + if (hRequest == null) { > + doLog(" authType", NON_HTTP_REQ_MSG); > + } else { > + doLog(" authType", hRequest.getAuthType()); > + } > + > + doLog(" contentType", response.getContentType()); > + > + if (hResponse == null) { > + doLog(" header", NON_HTTP_RES_MSG); > + } else { > + Iterable<String> rhnames = hResponse.getHeaderNames(); > + for (String rhname : rhnames) { > + Iterable<String> rhvalues = hResponse.getHeaders(rhname); > + for (String rhvalue : rhvalues) > + doLog(" header", rhname + "=" + rhvalue); > + } > + } > + > + if (hRequest == null) { > + doLog(" remoteUser", NON_HTTP_REQ_MSG); > + } else { > + doLog(" remoteUser", hRequest.getRemoteUser()); > + } > + > + if (hResponse == null) { > + doLog(" remoteUser", NON_HTTP_RES_MSG); > + } else { > + doLog(" status", > + Integer.valueOf(hResponse.getStatus()).toString()); > + } > + > + doLog("END TIME ", getTimestamp()); > + doLog("==================", > + "============================================"); > + } > + > + private void doLog(String attribute, String value) { > + StringBuilder sb = new StringBuilder(80); > + sb.append(Thread.currentThread().getName()); > + sb.append(' '); > + sb.append(attribute); > + sb.append('='); > + sb.append(value); > + log.info(sb.toString()); > + } > + > + private String getTimestamp() { > + Timestamp ts = timestamp.get(); > + long currentTime = System.currentTimeMillis(); > + > + if ((ts.date.getTime() + 999) < currentTime) { > + ts.date.setTime(currentTime - (currentTime % 1000)); > + ts.update(); > + } > + return ts.dateString; > + } > + > + @Override > + public void init(FilterConfig filterConfig) throws ServletException { > + // NOOP > + } > + > + @Override > + public void destroy() { > + // NOOP > + } > + > + private static final class Timestamp { > + private Date date = new Date(0); > + private SimpleDateFormat format = > + new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); > + private String dateString = format.format(date); > + private void update() { > + dateString = format.format(date); > + } > + } > +} > > Propchange: > tomcat/trunk/java/org/apache/catalina/filters/RequestDumperFilter.java > > ------------------------------------------------------------------------------ > svn:eol-style = native > > Propchange: > tomcat/trunk/java/org/apache/catalina/filters/RequestDumperFilter.java > > ------------------------------------------------------------------------------ > svn:keywords = Date Author Id Revision > > Modified: tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java > URL: > http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java?rev=805375&r1=805374&r2=805375&view=diff > > ============================================================================== > --- tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java (original) > +++ tomcat/trunk/java/org/apache/catalina/mbeans/MBeanFactory.java Tue Aug > 18 11:49:26 2009 > @@ -49,7 +49,6 @@ > import org.apache.catalina.valves.AccessLogValve; > import org.apache.catalina.valves.RemoteAddrValve; > import org.apache.catalina.valves.RemoteHostValve; > -import org.apache.catalina.valves.RequestDumperValve; > import org.apache.catalina.valves.ValveBase; > import org.apache.tomcat.util.modeler.BaseModelMBean; > > @@ -513,29 +512,6 @@ > > > /** > - * Create a new Request Dumper Valve. > - * > - * @param parent MBean Name of the associated parent component > - * > - * @exception Exception if an MBean cannot be created or registered > - */ > - public String createRequestDumperValve(String parent) > - throws Exception { > - > - // Create a new RequestDumperValve instance > - RequestDumperValve valve = new RequestDumperValve(); > - > - // Add the new instance to its parent component > - ObjectName pname = new ObjectName(parent); > - ContainerBase containerBase = getParentContainerFromParent(pname); > - containerBase.addValve(valve); > - ObjectName oname = valve.getObjectName(); > - return (oname.toString()); > - > - } > - > - > - /** > * Create a new Single Sign On Valve. > * > * @param parent MBean Name of the associated parent component > > Modified: tomcat/trunk/webapps/docs/config/filter.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/filter.xml?rev=805375&r1=805374&r2=805375&view=diff > > ============================================================================== > --- tomcat/trunk/webapps/docs/config/filter.xml (original) > +++ tomcat/trunk/webapps/docs/config/filter.xml Tue Aug 18 11:49:26 2009 > @@ -194,6 +194,75 @@ > </section> > > > +<section name="Request Dumper Filter"> > + > + <subsection name="Introduction"> > + > + <p>The Request Dumper Filter logs information from the request and > response > + objects and is intended to be used for debugging purposes. When using > this > + Filter, it is recommended that the > + <code>org.apache.catalina.filter.RequestDumperFilter</code> logger is > + directed to a dedicated file and that the > + <code>org.apache.juli.VerbatimFormmater</code> is used.</p> > + > + <p><strong>WARNING: Using this filter has side-effects.</strong> The > + output from this filter includes any parameters included with the > request. > + The parameters will be decoded using the default platform encoding. Any > + subsequent calls to <code>request.setCharacterEncoding()</code> within > + the web application will have no effect.</p> > + > + </subsection> > + > + <subsection name="Filter Class Name"> > + > + <p>The filter class name for the Request Dumper Filter is > + <strong><code>org.apache.catalina.filters.RequestDumperFilter</code> > + </strong>.</p> > + > + </subsection> > + > + <subsection name="Initialisation parameters"> > + > + <p>The Request Dumper Filter does not support any initialization > + parameters.</p> > + > + </subsection> > + > + <subsection name="Sample Configuration"> > + > + <p>The following entries in a web application's web.xml would enable the > + Request Dumper filter for all requests for that web application. If the > + entries were added to <code>CATALINA_BASE/conf/web.xml</code>, the > Request > + Dumper Filter would be enabled for all web applications.</p> > + <source> > +<filter> > + <filter-name>requestdumper</filter-name> > + <filter-class> > + org.apache.catalina.filters.RequestDumperFilter > + </filter-class> > +</filter> > +<filter-mapping> > + <filter-name>requestdumper</filter-name> > + <url-pattern>*</url-pattern> > +</filter-mapping> > + </source> > + > + <p>The following entries in CATALINA_BASE/conf/logging.properties would > + create a separate log file for the Request Dumper Filter output.</p> > + <source> > +# To this configuration below, 1request-dumper.org.apache.juli.FileHandler > +# also needs to be added to the handlers property near the top of the file > +1request-dumper.org.apache.juli.FileHandler.level = INFO > +1request-dumper.org.apache.juli.FileHandler.directory = > ${catalina.base}/logs > +1request-dumper.org.apache.juli.FileHandler.prefix = request-dumper. > +1request-dumper.org.apache.juli.FileHandler.formatter = > org.apache.juli.VerbatimFormatter > +org.apache.catalina.filters.RequestDumperFilter.level = INFO > +org.apache.catalina.filters.RequestDumperFilter.handlers = > 1request-dumper.org.apache.juli.FileHandler > + </source> > + </subsection> > +</section> > + > + > <section name="WebDAV Fix Filter"> > > <subsection name="Introduction"> > > Modified: tomcat/trunk/webapps/docs/config/valve.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/valve.xml?rev=805375&r1=805374&r2=805375&view=diff > > ============================================================================== > --- tomcat/trunk/webapps/docs/config/valve.xml (original) > +++ tomcat/trunk/webapps/docs/config/valve.xml Tue Aug 18 11:49:26 2009 > @@ -320,47 +320,6 @@ > </section> > > > -<section name="Request Dumper Valve"> > - > - > - <subsection name="Introduction"> > - > - <p>The <em>Request Dumper Valve</em> is a useful tool in debugging > - interactions with a client application (or browser) that is sending > - HTTP requests to your Tomcat-based server. When configured, it causes > - details about each request processed by its associated > <code>Engine</code>, > - <code>Host</code>, or <code>Context</code> to be logged according to > - the logging configuration for that container.</p> > - > - <p><strong>WARNING: Using this valve has side-effects.</strong> The > - output from this valve includes any parameters included with the > request. > - The parameters will be decoded using the default platform encoding. Any > - subsequent calls to <code>request.setCharacterEncoding()</code> within > - the web application will have no effect.</p> > - > - </subsection> > - > - > - <subsection name="Attributes"> > - > - <p>The <strong>Request Dumper Valve</strong> supports the following > - configuration attributes:</p> > - > - <attributes> > - > - <attribute name="className" required="true"> > - <p>Java class name of the implementation to use. This MUST be set > to > - <strong>org.apache.catalina.valves.RequestDumperValve</strong>.</p> > - </attribute> > - > - </attributes> > - > - </subsection> > - > - > -</section> > - > - > <section name="Single Sign On Valve"> > > <subsection name="Introduction"> > > Modified: tomcat/trunk/webapps/examples/WEB-INF/web.xml > URL: > http://svn.apache.org/viewvc/tomcat/trunk/webapps/examples/WEB-INF/web.xml?rev=805375&r1=805374&r2=805375&view=diff > > ============================================================================== > --- tomcat/trunk/webapps/examples/WEB-INF/web.xml (original) > +++ tomcat/trunk/webapps/examples/WEB-INF/web.xml Tue Aug 18 11:49:26 2009 > @@ -39,7 +39,7 @@ > > <filter> > <filter-name>Request Dumper Filter</filter-name> > - <filter-class>filters.RequestDumperFilter</filter-class> > + > <filter-class>org.apache.catalina.filters.RequestDumperFilter</filter-class> > </filter> > > <!-- Example filter to set character encoding on each request --> > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > For additional commands, e-mail: dev-h...@tomcat.apache.org > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org