Is there a way to measure Java (Servlet) I/O traff

2019-08-06 13:36发布

问题:

What I've tried to do is implement a servlet filter with such code:

int up = request.getContentLength();
if ( ( (HttpServletRequest) request ).getQueryString() != null )
  {
  up = Math.max( up, ( (HttpServletRequest) request ).getQueryString().length() ) ;
  }
int down = ( (HttpServletResponse) response ).getBufferSize();

processIO( up, down );

But, while the up vaue is largely OK, the down value is 8192 for every request.

Any hints appreciated, Ro

回答1:

getBufferSize()

Returns the actual buffer size used for the response. If no buffering is used, this method returns 0.

So of course the buffersize never changes! What you want is to get the response and then do size of that. Unfortunately, you can't do that with just HttpServletResponse. But you can implement your own ServletResponse and getContentLength. Make sure you do this after doFilter call.

EDIT:

Ok, I can't find a good example at the moment but here is an abstract what you can do. Implement your own response using wrapper and then for getOutputStream you can instead return your implementation. At the end of your Filter, just get the size of the stream.



回答2:

Filters happen before and after the request is handled: Is doFilter() executed before or after the Servlet's work is done?.

You must add something like this before int down = ...:

filterChain.doFilter(request, response);

This will invoke servlets (and other filters) that produce reply. Only then you can inspect the reply to see it's size.

Also, you are always getting 8192, because you are asking for a buffer size, not the size of reply.

Here is an example DumpFilter which logs all requests and responses. You can trim it down to just record request and response lengths.



回答3:

getBufferSize returns the buffer size, read the API doc. I think, you can calculate the down traffic in your code. Just increment a counter when your write to the servlet output stream.



回答4:

You can wrap a request and response and return a wrapped input and output stream accordingly. In those wrapped streams you can track how many bytes been read and written.

This way it would work not only with in-memory buffers, but also with large input and output streamed requests.