We want to measure the request and response sizes of our API endpoints. As it recommended to determine the duration with a RequestEventListener
we took that approach.
Using the inspector, we can see that the requestEvent contains a property containerResponse.messageContext.commitingOutputStream.adoptedOutput.delegate.outputStream.count
which contains the actual response size in bytes. However, we cannot access this field using public methods and fields. The accessible method containerResponse.getLength()
always returns -1
. The same for containerRequest.getLength()
.
How can we access the actual request and response sizes, preferably without reflection?
private class EndPointPerformanceFilter implements RequestEventListener {
private long start;
@Override
public void onEvent(final RequestEvent requestEvent) {
switch (requestEvent.getType()) {
case START:
start = timeProvider.currentTimeMillis();
break;
case FINISHED:
final long duration = timeProvider.currentTimeMillis() - start;
final ContainerRequest containerRequest = requestEvent.getContainerRequest();
final ContainerResponse containerResponse = requestEvent.getContainerResponse();
System.out.println("Req: [" + containerRequest.getLength() + "] Rep: [" + containerResponse.getLength() +"]");
break;
}
}
}
I tried to do the exact same thing before. I never found a solution that involved getting the data directly from Jersey. I just implemented a WriterInterceptor
where I set the OutputStream
to Apache Commons' CountingOutputStream
. Then got the count after the writer was finished.
I don't have the exact implementation on hand, but reproducing the functionality, it pretty much goes like this
@Provider
public class ContentLengthLoggingProvider implements ReaderInterceptor, WriterInterceptor {
private static final Logger logger = Logger.getLogger(ContentLengthLoggingProvider.class.getName());
private static final String REQUEST_LENGTH_PROPERTY = "Request.Content.Length";
@Override
public void aroundWriteTo(WriterInterceptorContext writerContext)
throws IOException, WebApplicationException {
CountingOutputStream outputStream
= new CountingOutputStream(writerContext.getOutputStream());
writerContext.setOutputStream(outputStream);
writerContext.proceed();
long responseCount = outputStream.getCount();
String requestCount = (String)writerContext.getProperty(REQUEST_LENGTH_PROPERTY);
String log = "Req: [" + requestCount + "] Rep: [" + responseCount +"]";
logger.info(log);
}
@Override
public Object aroundReadFrom(ReaderInterceptorContext readerContext)
throws IOException, WebApplicationException {
String requestLength = readerContext.getHeaders().getFirst(HttpHeaders.CONTENT_LENGTH);
readerContext.setProperty(REQUEST_LENGTH_PROPERTY, requestLength);
return readerContext.proceed();
}
}
This is the dependency I used
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
I think Guava has a similar CountingOutputStream
class. So if you are using Guava, you can also use that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.