Skip to content

Commit baab75a

Browse files
committed
Allow span decoration when exception thrown reading/writing
1 parent 55fc4c9 commit baab75a

File tree

4 files changed

+117
-9
lines changed

4 files changed

+117
-9
lines changed

opentracing-jaxrs2-itest/common/src/main/java/io/opentracing/contrib/jaxrs2/itest/common/AbstractServerTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,43 @@ public void testExceptionInHandler() {
212212
// Assert.assertEquals(500, mockSpan.tags().get(Tags.HTTP_STATUS.getKey()));
213213
}
214214

215+
@Test
216+
public void testExceptionInWriteInterceptor() {
217+
Client client = ClientBuilder.newClient();
218+
Response response = client.target(url("/failToSerialize"))
219+
.request()
220+
.get();
221+
response.close();
222+
Assert.assertEquals(500, response.getStatus());
223+
await().until(finishedSpansSizeEquals(2));
224+
225+
List<MockSpan> mockSpans = mockTracer.finishedSpans();
226+
Assert.assertEquals(2, mockSpans.size());
227+
MockSpan mockSpan = mockSpans.get(0);
228+
Assert.assertEquals(3, mockSpan.tags().size());
229+
Assert.assertEquals("serialize", mockSpan.operationName());
230+
Assert.assertEquals(true, mockSpan.tags().get(Tags.ERROR.getKey()));
231+
}
232+
233+
@Test
234+
public void testExceptionInReadInterceptor() {
235+
Client client = ClientBuilder.newClient();
236+
Response response = client.target(url("/failToDeserialize"))
237+
.request()
238+
.post(Entity.text("hello!"));
239+
response.close();
240+
// cxf returns 500 while jersey and resteasy returns 415
241+
Assert.assertTrue(response.getStatus() > 400);
242+
await().until(finishedSpansSizeEquals(2));
243+
244+
List<MockSpan> mockSpans = mockTracer.finishedSpans();
245+
Assert.assertEquals(2, mockSpans.size());
246+
MockSpan mockSpan = mockSpans.get(0);
247+
Assert.assertEquals(3, mockSpan.tags().size());
248+
Assert.assertEquals("deserialize", mockSpan.operationName());
249+
Assert.assertEquals(true, mockSpan.tags().get(Tags.ERROR.getKey()));
250+
}
251+
215252
@Test
216253
public void testMappedExceptionInHandler() {
217254
Client client = ClientBuilder.newClient();

opentracing-jaxrs2-itest/common/src/main/java/io/opentracing/contrib/jaxrs2/itest/common/rest/TestHandler.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.opentracing.contrib.jaxrs2.itest.common.rest;
22

3-
import io.opentracing.Scope;
43
import io.opentracing.Span;
54
import io.opentracing.SpanContext;
65
import io.opentracing.Tracer;
@@ -24,6 +23,10 @@
2423
import javax.ws.rs.core.Response;
2524
import org.eclipse.microprofile.opentracing.Traced;
2625
import org.junit.Assert;
26+
import javax.ws.rs.core.StreamingOutput;
27+
import java.io.IOException;
28+
import java.io.OutputStream;
29+
import java.util.Map;
2730

2831
/**
2932
* @author Pavol Loffay
@@ -94,6 +97,30 @@ public Response postWithBody(@Context HttpServletRequest request, String body) {
9497
return Response.ok().entity(body).build();
9598
}
9699

100+
@GET
101+
@Path("/failToSerialize")
102+
@Produces(MediaType.TEXT_PLAIN)
103+
@Consumes(MediaType.TEXT_PLAIN)
104+
public Response failToSerialize(@Context HttpServletRequest request) {
105+
assertActiveSpan();
106+
StreamingOutput output = new StreamingOutput() {
107+
@Override
108+
public void write(OutputStream output) throws IOException {
109+
throw new IOException("Fail to serialize");
110+
}
111+
};
112+
return Response.ok().entity(output).build();
113+
}
114+
115+
@POST
116+
@Path("/failToDeserialize")
117+
@Produces(MediaType.TEXT_PLAIN)
118+
@Consumes(MediaType.TEXT_PLAIN)
119+
public Response failToDeserialize(@Context HttpServletRequest request, Map<String, String> body) {
120+
assertActiveSpan();
121+
return Response.ok().build();
122+
}
123+
97124
@GET
98125
@Path("/path/{pathParam}")
99126
public Response pathParam(@PathParam("pathParam") String pathParam1) {

opentracing-jaxrs2/src/main/java/io/opentracing/contrib/jaxrs2/serialization/InterceptorSpanDecorator.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package io.opentracing.contrib.jaxrs2.serialization;
22

33
import io.opentracing.Span;
4+
import io.opentracing.tag.Tags;
5+
46
import javax.ws.rs.ext.InterceptorContext;
7+
import javax.ws.rs.ext.ReaderInterceptorContext;
8+
import javax.ws.rs.ext.WriterInterceptorContext;
59

610
public interface InterceptorSpanDecorator {
711

812
/**
9-
* Decorate spans by outgoing object.
13+
* Decorate spans by incoming object.
1014
*
1115
* @param context
1216
* @param span
@@ -21,6 +25,24 @@ public interface InterceptorSpanDecorator {
2125
*/
2226
void decorateWrite(InterceptorContext context, Span span);
2327

28+
/**
29+
* Decorate spans by error throw when processing incoming object.
30+
*
31+
* @param e
32+
* @param context
33+
* @param span
34+
*/
35+
void decorateReadException(Exception e, ReaderInterceptorContext context, Span span);
36+
37+
/**
38+
* Decorate spans by error thrown when processing outgoing object.
39+
*
40+
* @param e
41+
* @param context
42+
* @param span
43+
*/
44+
void decorateWriteException(Exception e, WriterInterceptorContext context, Span span);
45+
2446
/**
2547
* Adds tags: \"media.type\", \"entity.type\"
2648
*/
@@ -35,5 +57,15 @@ public void decorateRead(InterceptorContext context, Span span) {
3557
public void decorateWrite(InterceptorContext context, Span span) {
3658
decorateRead(context, span);
3759
}
60+
61+
@Override
62+
public void decorateReadException(Exception e, ReaderInterceptorContext context, Span span) {
63+
Tags.ERROR.set(span, true);
64+
}
65+
66+
@Override
67+
public void decorateWriteException(Exception e, WriterInterceptorContext context, Span span) {
68+
Tags.ERROR.set(span, true);
69+
}
3870
};
3971
}

opentracing-jaxrs2/src/main/java/io/opentracing/contrib/jaxrs2/serialization/TracingInterceptor.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import io.opentracing.Tracer;
77
import io.opentracing.contrib.jaxrs2.internal.SpanWrapper;
88
import io.opentracing.noop.NoopSpan;
9-
import io.opentracing.tag.Tags;
109
import java.io.IOException;
1110
import java.util.ArrayList;
1211
import java.util.Collection;
@@ -40,8 +39,7 @@ public Object aroundReadFrom(ReaderInterceptorContext context)
4039
try {
4140
return context.proceed();
4241
} catch (Exception e) {
43-
//TODO add exception logs in case they are not added by the filter.
44-
Tags.ERROR.set(span, true);
42+
decorateReadException(e, context, span);
4543
throw e;
4644
}
4745
} finally {
@@ -55,10 +53,12 @@ public void aroundWriteTo(WriterInterceptorContext context)
5553
Span span = buildSpan(context, "serialize");
5654
try (Scope scope = tracer.activateSpan(span)) {
5755
decorateWrite(context, span);
58-
context.proceed();
59-
} catch (Exception e) {
60-
Tags.ERROR.set(span, true);
61-
throw e;
56+
try {
57+
context.proceed();
58+
} catch (Exception e) {
59+
decorateWriteException(e, context, span);
60+
throw e;
61+
}
6262
} finally {
6363
span.finish();
6464
}
@@ -106,4 +106,16 @@ private void decorateWrite(InterceptorContext context, Span span) {
106106
decorator.decorateWrite(context, span);
107107
}
108108
}
109+
110+
private void decorateReadException(Exception e, ReaderInterceptorContext context, Span span) {
111+
for (InterceptorSpanDecorator decorator : spanDecorators) {
112+
decorator.decorateReadException(e, context, span);
113+
}
114+
}
115+
116+
private void decorateWriteException(Exception e, WriterInterceptorContext context, Span span) {
117+
for (InterceptorSpanDecorator decorator : spanDecorators) {
118+
decorator.decorateWriteException(e, context, span);
119+
}
120+
}
109121
}

0 commit comments

Comments
 (0)