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>
>  +&lt;filter&gt;
>  +    &lt;filter-name&gt;requestdumper&lt;/filter-name&gt;
>  +    &lt;filter-class&gt;
>  +        org.apache.catalina.filters.RequestDumperFilter
>  +    &lt;/filter-class&gt;
>  +&lt;/filter&gt;
>  +&lt;filter-mapping&gt;
>  +    &lt;filter-name&gt;requestdumper&lt;/filter-name&gt;
>  +    &lt;url-pattern&gt;*&lt;/url-pattern&gt;
>  +&lt;/filter-mapping&gt;
>  +    </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

Reply via email to