You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Steve Karlovic <st...@gmail.com> on 2013/03/14 03:59:36 UTC

Capturing time to marshal and send

Hello,
I am using CXF for RESTful services. I would like to capture the time it takes to marshal the response separately from the time it takes to write the response and send it to the client. It seems like the JAXRSOutInterceptor is responsible for the marshalling. Immediately after marshalling it appears that the write occurs as well. Is there a way to have a method I write in my own class to be called as soon as the response is marshalled but before the data is sent? Is there another interceptor I should be looking at as well? We are using 2.6.1.

Thanks,
Steve

Re: Capturing time to marshal and send

Posted by SK <sk...@gmail.com>.
Thanks Sergey, I'll give it a shot.

- Steve

On Mar 14, 2013, at 3:39 AM, Sergey Beryozkin <sb...@gmail.com> wrote:

> Hi
> On 14/03/13 02:59, Steve Karlovic wrote:
>> Hello,
>> I am using CXF for RESTful services. I would like to capture the time it takes to marshal the response separately from the time it takes to write the response and send it to the client. It seems like the JAXRSOutInterceptor is responsible for the marshalling. Immediately after marshalling it appears that the write occurs as well. Is there a way to have a method I write in my own class to be called as soon as the response is marshalled but before the data is sent? Is there another interceptor I should be looking at as well? We are using 2.6.1.
> Assuming it is JAXB, what you can do is to register a custom XMLStreamWriter which will calculate the time between writeStartDocument and writeStartDocument.
> 
> The custom writer can be registered from the out CXF interceptor or ResponseHandler filter, like this:
> 
> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java
> 
> (see the two lines within the 'if' branch), on the trunk it is JAX-RS 2.0 ContainerResponseFilter which does it, but the same two lines will work in CXF 2.6.2 when done from the interceptor or ResponseHandler filter.
> 
> The actual custom interceptor may look like this:
> http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java
> 
> except that all you will have to do is to override writeStartDocument & writeEndDocument instead
> 
> This will give you the time it takes to marshal.
> 
> Catching the actual time when the response has been sent can be trickier I guess. In JAX-RS 2.0 one can use
> 
> http://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/container/CompletionCallback.html
> 
> CXF will actually callback on it when the relevant async servlet callback is called, so it can be really close.
> 
> but that will work for the code using 2.0 AsyncResponse only, starting from 2.7.x.
> 
> I guess, what you can try to do is to replace an OutputStream on the message,
> 
> OutputStream os = outMessage.getContent(OutputStream.class);
> and wrap it with some filtered output stream that will catch when say flush() is called, I'm not exactly sure how precise the data you can get with this approach. Another option may be is to replace HttpServletResponse with a wrapper (can be done from a servlet filter or even from CXF interceptor, it is registered on the inbound message as "HTTP.RESPONSE"), and override its ServletOutputStream, etc.
> 
> HTH, Sergey
> 
>> Thanks,
>> Steve
> 

Re: Capturing time to marshal and send

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 14/03/13 02:59, Steve Karlovic wrote:
> Hello,
> I am using CXF for RESTful services. I would like to capture the time it takes to marshal the response separately from the time it takes to write the response and send it to the client. It seems like the JAXRSOutInterceptor is responsible for the marshalling. Immediately after marshalling it appears that the write occurs as well. Is there a way to have a method I write in my own class to be called as soon as the response is marshalled but before the data is sent? Is there another interceptor I should be looking at as well? We are using 2.6.1.
>
Assuming it is JAXB, what you can do is to register a custom 
XMLStreamWriter which will calculate the time between writeStartDocument 
and writeStartDocument.

The custom writer can be registered from the out CXF interceptor or 
ResponseHandler filter, like this:

http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java

(see the two lines within the 'if' branch), on the trunk it is JAX-RS 
2.0 ContainerResponseFilter which does it, but the same two lines will 
work in CXF 2.6.2 when done from the interceptor or ResponseHandler filter.

The actual custom interceptor may look like this:
http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java

except that all you will have to do is to override writeStartDocument & 
writeEndDocument instead

This will give you the time it takes to marshal.

Catching the actual time when the response has been sent can be trickier 
I guess. In JAX-RS 2.0 one can use

http://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/container/CompletionCallback.html

CXF will actually callback on it when the relevant async servlet 
callback is called, so it can be really close.

but that will work for the code using 2.0 AsyncResponse only, starting 
from 2.7.x.

I guess, what you can try to do is to replace an OutputStream on the 
message,

OutputStream os = outMessage.getContent(OutputStream.class);
and wrap it with some filtered output stream that will catch when say 
flush() is called, I'm not exactly sure how precise the data you can get 
with this approach. Another option may be is to replace 
HttpServletResponse with a wrapper (can be done from a servlet filter or 
even from CXF interceptor, it is registered on the inbound message as 
"HTTP.RESPONSE"), and override its ServletOutputStream, etc.

HTH, Sergey

> Thanks,
> Steve