Java Mailing List Archive

http://www.junlu.com/

Home » Home (12/2007) » Apache Tomcat »

Re: Logging all data sent to client

benshort

2007-07-24

Replies:

Heres what I have put together, use at your own risk. any comments welcome.

HttpServletResponseLoggingFilter.java

public class HttpServletResponseLoggingFilter implements Filter
  {
  private Logger mLogger =
Logger.getLogger(HttpServletResponseLoggingFilter.class);

  public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain) throws
IOException, ServletException
    {
    if ( mLogger.isDebugEnabled() && servletResponse instanceof
HttpServletResponse &&
isNonStaticResource((HttpServletRequest)servletRequest) )
       {
       final LoggingHttpServletResponse
loggingHttpServletResponse = new
LoggingHttpServletResponse((HttpServletResponse)servletResponse);

       try
          {
          mLogger.debug("Filtering request : " +
getFullRequestUrl((HttpServletRequest)servletRequest));

          filterChain.doFilter(servletRequest,
loggingHttpServletResponse);
          }
       finally
          {
          loggingHttpServletResponse.finishResponse();
          }
       }
    else
       {
       filterChain.doFilter(servletRequest, servletResponse);
       }
    }

  private boolean isNonStaticResource(HttpServletRequest request)
    {
    return !request.getRequestURI().contains("resources");
    }

  // http://hostname.com/mywebapp/servlet/MyServlet/a/b;c=123?d=789
  private String getFullRequestUrl(HttpServletRequest request)
    {
    String reqUrl = request.getRequestURL().toString();
    String queryString = request.getQueryString();  // d=789
    if (queryString != null)
       {
       reqUrl += "?"+queryString;
       }
    return reqUrl;
    }

  public void init(FilterConfig filterConfig) throws ServletException
    {
    }

  public void destroy()
    {
    }

  }

LoggingHttpServletResponse.java

class LoggingHttpServletResponse extends HttpServletResponseWrapper
  {
  private Logger mLogger = Logger.getLogger(LoggingHttpServletResponse.class);

  public LoggingHttpServletResponse(HttpServletResponse httpServletResponse)
    {
    super(httpServletResponse);
    mWrappedResponse = httpServletResponse;
    }

  // ----------------------------------------------------- Instance Variables

  /**
  * Original response
  */

  protected HttpServletResponse mWrappedResponse = null;

  /**
  * The ServletOutputStream that has been returned by
  * <code>getOutputStream()</code>, if any.
  */

  protected ServletOutputStream mStream = null;


  /**
  * The PrintWriter that has been returned by
  * <code>getWriter()</code>, if any.
  */

  protected PrintWriter mWriter = null;

  // --------------------------------------------------------- Public Methods

  /**
  * Create and return a ServletOutputStream to write the content
  * associated with this Response.
  *
  * @throws IOException if an input/output error occurs
  */
  public ServletOutputStream createOutputStream() throws IOException
    {
    mLogger.debug("Creating new LoggingOutputStream");

    return new LoggingServletOutputStream(mWrappedResponse, mLogger);
    }


  /**
  * Finish a response.
  */
  public void finishResponse()
    {
    try
       {
       if (mWriter != null)
          {
          mWriter.close();
          }
       else
          {
          if (mStream != null)
            mStream.close();
          }
       }
    catch (IOException e)
       {
       }
    }

  // ------------------------------------------------ ServletResponse Methods


  /**
  * Flush the buffer and commit this response.
  *
  * @throws IOException if an input/output error occurs
  */
  public void flushBuffer() throws IOException
    {
    mStream.flush();
    }

  /**
  * Return the servlet output mStream associated with this Response.
  *
  * @throws IllegalStateException if <code>getWriter</code> has
  *                     already been called for this response
  * @throws IOException       if an input/output error occurs
  */
  public ServletOutputStream getOutputStream() throws IOException
    {
    if (mWriter != null)
       throw new IllegalStateException("getWriter() has already
been called for this response");

    if (mStream == null)
       mStream = createOutputStream();

    mLogger.debug("mStream is set to " + mStream + " in getOutputStream");

    return (mStream);
    }

  /**
  * Return the mWriter associated with this Response.
  *
  * @throws IllegalStateException if <code>getOutputStream</code> has
  *                     already been called for this response
  * @throws IOException       if an input/output error occurs
  */
  public PrintWriter getWriter() throws IOException
    {
    if (mWriter != null)
       return (mWriter);

    if (mStream != null)
       throw new IllegalStateException("getOutputStream() has
already been called for this response");

    mStream = createOutputStream();

    mLogger.debug("mStream is set to " + mStream + " in getOutputStream");

    // HttpServletResponse.getCharacterEncoding() shouldn't return null
    // according the spec, so feel free to remove that "if"
    mWriter = new PrintWriter(mStream);

    return (mWriter);
    }

  }

LoggingServletOutputStream.java

class LoggingServletOutputStream extends ServletOutputStream
  {
  private Logger mLogger;
  private HttpServletResponse mResponse;
  private OutputStream mOutputStream;
  private ByteArrayOutputStream mByteArrayOutputStream = new
ByteArrayOutputStream();

  public LoggingServletOutputStream(HttpServletResponse response,
Logger logger) throws IOException
    {
    mResponse = response;
    mOutputStream = mResponse.getOutputStream();
    mLogger = logger;
    }

  public void write(int b) throws IOException
    {
    mByteArrayOutputStream.write(b);
    mOutputStream.write(b);
    }

  @Override
  public void write(byte b[]) throws IOException
    {
    mByteArrayOutputStream.write(b);
    mOutputStream.write(b);
    }

  @Override
  public void write(byte b[], int off, int len) throws IOException
    {
    mByteArrayOutputStream.write(b, off, len);
    mOutputStream.write(b, off, len);
    }

  @Override
  public void close() throws IOException
    {
    if ( mLogger.isDebugEnabled() )
       {
       float kBytes = mByteArrayOutputStream.size() / 1024f;

       mLogger.debug("Writing " + kBytes + " kb (" +
mByteArrayOutputStream.size() +" b) to the client.\n" +
mByteArrayOutputStream.toString());
       }

    mByteArrayOutputStream = null;
    mOutputStream.close();
    }

  @Override
  public void flush() throws IOException
    {
    mOutputStream.flush();
    }
  }

web.xml Snippit..

<filter>
    <filter-name>Logging Filter</filter-name>
    <filter-class>com.nexusalpha.journeycheck.presentation.debug.HttpServletResponseLoggingFilter</filter-class>
  </filter>

  <filter-mapping>
   <filter-name>Logging Filter</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>







On 7/24/07, ben short <ben@(protected):
> Yes sure.
>
> On 7/24/07, Karel V Sedlacek <kvs1@(protected):
> > Ben,
> >
> > When you succeed at this would you pass along your code? We have issues
> > with timeouts and it would be great to see what's being passed along to
> > the client.
> >
> > Karel
> > Cornell University
> >
> > > Yes from the CompressionServletResponseWrapper example I can see the
> > > methods I need to override as you have pointed out.
> > >
> > > On 7/24/07, Tim Funk <funkman@(protected):
> > >> Yes - but tomcat doesn't have that functionality out of the box - you'd
> > >> need to write a filter which creates a HttpServletRequestWrapper which
> > >> overrides getOutputStream() (or getWriter()) and then passes back a
> > >> wrapped OutStream or Writer which also logs to wherever when print(int
> > >> i) is called.
> > >>
> > >> -Tim
> > >>
> > >> ben short wrote:
> > >> > Hi Tim,
> > >> >
> > >> > Thanks for that, but it only seems to log out the request/response
> > >> > headers. Is It possible to log everything sent to the client?
> > >> >
> > >> > Ben
> > >> >
> > >> > On 7/24/07, Tim Funk <funkman@(protected):
> > >> >> Look at the RequestDumperValve
> > >> >>
> > >> >> -Tim
> > >> >>
> > >> >> ben short wrote:
> > >> >> > Hi,
> > >> >> >
> > >> >> > I using Tomcat 6.0.13 and Spring 2.0.6. I have been involved in
> > >> >> > developing a website that products pages in various formats , such
> > >> as
> > >> >> > www, xml, wap and pda. We are having some issues with wap and pda,
> > >> but
> > >> >> > cant ciew the html source thats being shown on the devices.
> > >> >> > We can view the html source in firefox using a wap and pda plugin,
> > >> but
> > >> >> > the issues are not always the same or there at all.
> > >> >> >
> > >> >> > What I would like to do is log all the data sent to the client. I
> > >> have
> > >> >> > been looking at encapsulating the HttpServletRequest and log out
> > >> the
> > >> >> > data to a log file.
> > >>
> > >> ---------------------------------------------------------------------
> > >> To start a new topic, e-mail: users@(protected)
> > >> To unsubscribe, e-mail: users-unsubscribe@(protected)
> > >> For additional commands, e-mail: users-help@(protected)
> > >>
> > >>
> > >
> > > ---------------------------------------------------------------------
> > > To start a new topic, e-mail: users@(protected)
> > > To unsubscribe, e-mail: users-unsubscribe@(protected)
> > > For additional commands, e-mail: users-help@(protected)
> > >
> > >
> >
> >
> >
> > ---------------------------------------------------------------------
> > To start a new topic, e-mail: users@(protected)
> > To unsubscribe, e-mail: users-unsubscribe@(protected)
> > For additional commands, e-mail: users-help@(protected)
> >
> >
>

---------------------------------------------------------------------
To start a new topic, e-mail: users@(protected)
To unsubscribe, e-mail: users-unsubscribe@(protected)
For additional commands, e-mail: users-help@(protected)

©2008 junlu.com - Jax Systems, LLC, U.S.A.