Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tracing for entity reading and writing. #46

Merged

Conversation

hypnoce
Copy link
Contributor

@hypnoce hypnoce commented Oct 22, 2017

Hi all,

I added reader and writer interceptors to measure serialization time.
The code of the client and server are almost the same. I can factorise them if needs be.
Let me know if you have any comment on the feature itself and on the implementation. I will be happy to hear them.

Thanks

@hypnoce hypnoce changed the title A tracing for entity reading and writing. Add tracing for entity reading and writing. Oct 22, 2017
@hypnoce hypnoce force-pushed the serialization_tracing branch 4 times, most recently from cebdfa4 to ea0e6d9 Compare October 22, 2017 22:18
@pavolloffay
Copy link
Collaborator

@hypnoce hi, thanks for a nice contribution!

I have a couple of general comments:

  • client and server interceptors could be unified, we would have just one tracing interceptor (for both client and server).
  • decorators for operation names are redundant. Default operation names could be hardcoded as serialize and deserialize respectively.

@hypnoce
Copy link
Contributor Author

hypnoce commented Oct 24, 2017

No problem, I will make the needed changes when I'm out of meetings :)

Copy link
Collaborator

@pavolloffay pavolloffay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good. We need to change reference types to be semantically correct.

@@ -39,7 +39,7 @@ public void testDefaultOperationNameAndTags() {
.get();
response.close();

Assert.assertEquals(1, mockTracer.finishedSpans().size());
Assert.assertEquals(2, mockTracer.finishedSpans().size());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please also test the second span?

}

private void assertSerializationSpan(MockSpan parentSpan, MockSpan serializationSpan) {
Assert.assertTrue(Objects.toString(serializationSpan.tags().get("media.type")).contains(MediaType.TEXT_PLAIN));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert.equals is better here. The same for server tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resteasy client returns the charset. Will make sure to remove it before assertion.

@Path("/postWithBody")
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.TEXT_PLAIN)
public Response postWithBody(@Context HttpServletRequest request, String body) throws ExecutionException, InterruptedException {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can have only this endpoint and remove putWithBody and get


@Test
public void testSerializationResponseAndRequestWithBody() {
String response = client.target(url("/postWithBody"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please use ClientBuilder.newClient() here? There is already a test for testing if wiring works properly.

List<MockSpan> mockSpans = mockTracer.finishedSpans();
Assert.assertEquals(2, mockSpans.size());

final MockSpan serializationSpan = mockSpans.get(1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client requests

Server requests

  • Deserialization happens between the span in the server filter is started and finished so we can use child_of
  • Serialization of response entity happens after the server span if finished so we can use only follows_from. (a note for me: If we integrate with servlet filter Integrate with servlet filter #13 then the wrapping span would be always finished after writing the entity).

For more see: https://jersey.github.io/documentation/latest/user-guide.html#d0e9613

If we are going to unify interceptors then we have to do:

  1. use the same name for span wrappers
  2. check if span wrapper has been finished or not when starting a serialization/deserialization span

@@ -27,7 +30,7 @@ public void testServerStandardTags() throws Exception {
.get();
response.close();

Assert.assertEquals(1, mockTracer.finishedSpans().size());
Assert.assertEquals(2, mockTracer.finishedSpans().size());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please remove server entities from /clientTracingChaining and "/hello/{id} so the tests remain as they are?

@hypnoce hypnoce force-pushed the serialization_tracing branch 4 times, most recently from 00f96d1 to 2cd62a2 Compare October 30, 2017 09:15
@hypnoce
Copy link
Contributor Author

hypnoce commented Oct 30, 2017

@pavolloffay I made the changes according to your helpful comments. Let me know if there is anything else.

Copy link
Collaborator

@pavolloffay pavolloffay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look good just a couple of comments.

import io.opentracing.BaseSpan;
import javax.ws.rs.ext.InterceptorContext;

public interface SerdeInterceptorSpanDecorator {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a typo Serde

import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;

public abstract class SerdeTracingInterceptor implements WriterInterceptor, ReaderInterceptor {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a typo Serde

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name just TracingInterceptor would work.

if(spanWrapper == null) {
return NoopActiveSpanSource.NoopActiveSpan.INSTANCE;
}
final Tracer.SpanBuilder serdeSpanBuilder = tracer.buildSpan(operationName);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo serde?

/**
* Set static serialization operation names.
*/
SerdeInterceptorSpanDecorator SERIALIZE_OPERATION_NAME = new SerdeInterceptorSpanDecorator() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need this decorator, it uses the same operation names as hardcoded ones.

* Use the current HttpServletRequest to lookup the current span wrapper.
*/
@Context
private HttpServletRequest servletReq;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) we see more differences between impls

try {
return context.proceed();
} catch (Exception e) {
Tags.ERROR.set(activeSpan, true);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a todo here

// Add exception logs in case they are not added by the filter.

@hypnoce
Copy link
Contributor Author

hypnoce commented Oct 31, 2017

@pavolloffay I used 'serde' as a convention when dealing with serialisation and deserialisation classes. I saw this in kafka I think :). Removed.
I made the changes. Let me know if that looks fine ! Thanks

@hypnoce
Copy link
Contributor Author

hypnoce commented Nov 2, 2017

@pavolloffay I just noticed something : the follows_from reference is never used. Indeed, in case of a synchronous request, the spanWrapper object is never finished.

Therefore, when checking for completion in TracingInterceptor, the spanWrapper is not finished but the actual underlying span is. Also, in the mock tracing library, there is no simple way to check for follows_from reference type as it is added as a normal parent.

@pavolloffay
Copy link
Collaborator

I will have a look at this PR today.

Also, in the mock tracing library, there is no simple way to check for follows_from reference type as it is added as a normal parent.

agree mock tracer does not support it, either multiple references. I will create an issue in upstream.

@pavolloffay
Copy link
Collaborator

MockTracer issue opentracing/opentracing-java#210.

@hypnoce you are right

is a bug for sync requests the wrapper is not finished.

I will do a fix PR and then retest this.

@hypnoce
Copy link
Contributor Author

hypnoce commented Nov 2, 2017

@pavolloffay I made a fix on my side. But hard to test unless I had a filter to get the spanWrapper and check if it's finished.

@pavolloffay pavolloffay mentioned this pull request Nov 2, 2017
@pavolloffay
Copy link
Collaborator

pavolloffay commented Nov 2, 2017

The fix is here #47

@hypnoce
Copy link
Contributor Author

hypnoce commented Nov 2, 2017

Rebased. I still cannot test for follows_from. Do you want to wait until we can properly validate this ?

@pavolloffay
Copy link
Collaborator

I think it will take a longer time to get it implemented in OT API. We can create an issue to fix it :)

Copy link
Collaborator

@pavolloffay pavolloffay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a minor comments, It looks great!

@@ -10,6 +10,8 @@
*/
public class SpanWrapper {

public static final String SPAN_PROP_ID = SpanWrapper.class.getName() + ".activeSpanWrapper";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can change it to PROPERTY_NAME.

@@ -78,13 +81,15 @@ public void testAsyncSever() throws Exception {
response.close();

List<MockSpan> mockSpans = mockTracer.finishedSpans();
Assert.assertEquals(2, mockSpans.size());
Assert.assertEquals(3, mockSpans.size());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please change /async endpoint to not return any value so the interceptor does not kick in.

@hypnoce
Copy link
Contributor Author

hypnoce commented Nov 5, 2017

@pavolloffay made changes according to your last comments. Added a PR for exposing reference type from MockSpan : opentracing/opentracing-java#213

@pavolloffay
Copy link
Collaborator

@hypnoce thanks. I will merge and create an issue to test it.

@pavolloffay pavolloffay merged commit 1062ce5 into opentracing-contrib:master Nov 6, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants