title: How to use a filter to measure performance?
body: <p>I'm wondering if I can use a filter (in my case a CorsFilter) to measure timing AND to put the time taken onto the message itself. I know that the following works ok:</p>
  
  <pre><code>public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
    long startTime = System.nanoTime();
    chain.doFilter(request, response);
    long endTime = System.nanoTime();
    System.out.println("Time: " + (endTime - startTime) );
  }
  </code></pre>
  
  <p>Which of course outputs the total time in seconds. I wanted to put the time into the header of the returned response so that the receiver could look at the header and see how long processing took. The following code doesn't work:</p>
  
  <pre><code>public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
    long startTime = System.nanoTime();
    if(response instanceof HttpServletResponse) {
      HttpServletResponse httpResp = (HttpServletResponse)response;
      httpResp.addHeader("Start-time", Long.toString(startTime));
    }
  
    chain.doFilter(request, response);
    long endTime = System.nanoTime();
    if(response instanceof HttpServletResponse) {
      HttpServletResponse httpResp = (HttpServletResponse)response;
      httpResp.addHeader("End-time", Long.toString(endTime));
    }
  }
  </code></pre>
  
  <p>The header only includes Start-time and not End-time. I'm assuming that this is because the message has already been sent so modifying the object will have no effect. </p>
  
  <p>Does anyone have an elegant / clever solution to put timings into the header through the use of a filter?</p>
  
  <p>Thanks,
  Phil</p>
  
  <p><strong>Update</strong></p>
  
  <p>I've investigated the use of a HttpServletResponseWrapper to address this solution. This still fails to output either XXX-EndTime or YYY-EndTime on the response header.</p>
  
  <pre><code>@Override
  public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
    long startTime = System.nanoTime();
  
    if(response instanceof HttpServletResponse) {
      HttpServletResponse httpResp = (HttpServletResponse)response;
      httpResp.addHeader("Access-Control-Allow-Origin", "*");
      httpResp.addHeader("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS");
      httpResp.addHeader("Allow", "GET, HEAD, OPTIONS");
      httpResp.addHeader("Access-Control-Allow-Headers", "*");
      httpResp.addHeader("A-Runtime", Long.toString(startTime));
    }
  
    OutputStream out = response.getOutputStream();
  
    GenericResponseWrapper wrapper = new GenericResponseWrapper((HttpServletResponse) response);
  
    chain.doFilter(request,wrapper);
  
    out.write(wrapper.getData());
  
    if(response instanceof HttpServletResponse) {
  HttpServletResponse httpResp = (HttpServletResponse)response;
  httpResp.addHeader("XXX-EndTime", Long.toString(System.nanoTime() - startTime));
  
      wrapper.addHeader("YYY-EndTime", Long.toString(System.nanoTime() - startTime));
    }
  
    out.close();
  }
  </code></pre>