Move servlet tests to individual modules. Fix servlet 2 instrumentation.
Turns out we weren’t actually servlet 2 compatible. That should be fixed now. Unfortunately it appears servlet 2 also doesn’t expose the http response code, so we aren’t able to set it as a tag without custom instrumentation for each framework. I also removed our log4j2 stuff since we’re using logback.
This commit is contained in:
parent
1a855c4271
commit
3e57a7a7ea
|
@ -24,6 +24,7 @@ dependencies {
|
||||||
testCompile project(':dd-trace-ot')
|
testCompile project(':dd-trace-ot')
|
||||||
|
|
||||||
testCompile deps.opentracingMock
|
testCompile deps.opentracingMock
|
||||||
|
testCompile deps.testLogging
|
||||||
|
|
||||||
testCompile(project(':dd-java-agent:testing')) {
|
testCompile(project(':dd-java-agent:testing')) {
|
||||||
// Otherwise this can bring in classes that aren't "shadowed"
|
// Otherwise this can bring in classes that aren't "shadowed"
|
||||||
|
@ -36,16 +37,9 @@ dependencies {
|
||||||
// run embeded mongodb for integration testing
|
// run embeded mongodb for integration testing
|
||||||
testCompile group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '1.50.5'
|
testCompile group: 'de.flapdoodle.embed', name: 'de.flapdoodle.embed.mongo', version: '1.50.5'
|
||||||
|
|
||||||
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.2.0.v20160908'
|
|
||||||
testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.2.0.v20160908'
|
|
||||||
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '8.0.41'
|
|
||||||
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '8.0.41'
|
|
||||||
testCompile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3'
|
testCompile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.3'
|
||||||
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
|
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
|
||||||
|
|
||||||
testCompile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.8.2'
|
|
||||||
testCompile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.8.2'
|
|
||||||
|
|
||||||
// JDBC tests:
|
// JDBC tests:
|
||||||
testCompile group: 'com.h2database', name: 'h2', version: '1.4.196'
|
testCompile group: 'com.h2database', name: 'h2', version: '1.4.196'
|
||||||
testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.3.+'
|
testCompile group: 'org.hsqldb', name: 'hsqldb', version: '2.3.+'
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
appender.console.type=Console
|
|
||||||
appender.console.name=console
|
|
||||||
appender.console.layout.type=PatternLayout
|
|
||||||
rootLogger.level=debug
|
|
||||||
rootLogger.appenderRef.console.ref=console
|
|
|
@ -24,4 +24,11 @@ dependencies {
|
||||||
compile deps.bytebuddy
|
compile deps.bytebuddy
|
||||||
compile deps.opentracing
|
compile deps.opentracing
|
||||||
compile deps.autoservice
|
compile deps.autoservice
|
||||||
|
|
||||||
|
testCompile project(':dd-java-agent:testing')
|
||||||
|
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '7.0.0.v20091005'
|
||||||
|
testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '7.0.0.v20091005'
|
||||||
|
|
||||||
|
testCompile project(':dd-java-agent:instrumentation:okhttp-3') // used in the tests
|
||||||
|
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.SpanContext;
|
import io.opentracing.SpanContext;
|
||||||
import io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter;
|
import io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter;
|
||||||
import io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator;
|
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
@ -52,10 +51,7 @@ public final class FilterChain2Instrumentation extends Instrumenter.Configurable
|
||||||
new HelperInjector(
|
new HelperInjector(
|
||||||
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter",
|
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter",
|
||||||
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||||
"io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator",
|
"datadog.trace.instrumentation.servlet2.ServletFilterSpanDecorator"))
|
||||||
"io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator$1",
|
|
||||||
"io.opentracing.contrib.web.servlet.filter.TracingFilter",
|
|
||||||
"io.opentracing.contrib.web.servlet.filter.TracingFilter$1"))
|
|
||||||
.transform(
|
.transform(
|
||||||
DDAdvice.create()
|
DDAdvice.create()
|
||||||
.advice(
|
.advice(
|
||||||
|
|
|
@ -19,7 +19,6 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.SpanContext;
|
import io.opentracing.SpanContext;
|
||||||
import io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter;
|
import io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter;
|
||||||
import io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator;
|
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
@ -52,12 +51,9 @@ public final class HttpServlet2Instrumentation extends Instrumenter.Configurable
|
||||||
new HelperInjector(
|
new HelperInjector(
|
||||||
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter",
|
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter",
|
||||||
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
"io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter$MultivaluedMapFlatIterator",
|
||||||
"io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator",
|
"datadog.trace.instrumentation.servlet2.ServletFilterSpanDecorator"))
|
||||||
"io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator$1",
|
|
||||||
"io.opentracing.contrib.web.servlet.filter.TracingFilter",
|
|
||||||
"io.opentracing.contrib.web.servlet.filter.TracingFilter$1"))
|
|
||||||
.transform(
|
.transform(
|
||||||
DDAdvice.create()
|
DDAdvice.create(false) // Can't use the error handler for pre 1.5 classes...
|
||||||
.advice(
|
.advice(
|
||||||
named("service")
|
named("service")
|
||||||
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
.and(takesArgument(0, named("javax.servlet.http.HttpServletRequest")))
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
package datadog.trace.instrumentation.servlet2;
|
||||||
|
|
||||||
|
import io.opentracing.Span;
|
||||||
|
import io.opentracing.tag.Tags;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpanDecorator to decorate span at different stages in filter processing (before
|
||||||
|
* filterChain.doFilter(), after and if exception is thrown).
|
||||||
|
*
|
||||||
|
* <p>Taken from
|
||||||
|
* https://raw.githubusercontent.com/opentracing-contrib/java-web-servlet-filter/v0.1.0/opentracing-web-servlet-filter/src/main/java/io/opentracing/contrib/web/servlet/filter/ServletFilterSpanDecorator.java
|
||||||
|
* and removed async and status code stuff to be Servlet 2.x compatible.
|
||||||
|
*
|
||||||
|
* @author Pavol Loffay
|
||||||
|
*/
|
||||||
|
public interface ServletFilterSpanDecorator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorate span before {@link javax.servlet.Filter#doFilter(ServletRequest, ServletResponse,
|
||||||
|
* FilterChain)} is called. This is called right after span in created. Span is already present in
|
||||||
|
* request attributes with name {@link TracingFilter#SERVER_SPAN_CONTEXT}.
|
||||||
|
*
|
||||||
|
* @param httpServletRequest request
|
||||||
|
* @param span span to decorate
|
||||||
|
*/
|
||||||
|
void onRequest(HttpServletRequest httpServletRequest, Span span);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorate span after {@link javax.servlet.Filter#doFilter(ServletRequest, ServletResponse,
|
||||||
|
* FilterChain)}.
|
||||||
|
*
|
||||||
|
* @param httpServletRequest request
|
||||||
|
* @param httpServletResponse response
|
||||||
|
* @param span span to decorate
|
||||||
|
*/
|
||||||
|
void onResponse(
|
||||||
|
HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Span span);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorate span when an exception is thrown during processing in {@link
|
||||||
|
* javax.servlet.Filter#doFilter(ServletRequest, ServletResponse, FilterChain)}.
|
||||||
|
*
|
||||||
|
* @param httpServletRequest request
|
||||||
|
* @param exception exception
|
||||||
|
* @param span span to decorate
|
||||||
|
*/
|
||||||
|
void onError(
|
||||||
|
HttpServletRequest httpServletRequest,
|
||||||
|
HttpServletResponse httpServletResponse,
|
||||||
|
Throwable exception,
|
||||||
|
Span span);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorate span on asynchronous request timeout.
|
||||||
|
*
|
||||||
|
* @param httpServletRequest request
|
||||||
|
* @param httpServletResponse response
|
||||||
|
* @param timeout timeout
|
||||||
|
* @param span span to decorate
|
||||||
|
*/
|
||||||
|
void onTimeout(
|
||||||
|
HttpServletRequest httpServletRequest,
|
||||||
|
HttpServletResponse httpServletResponse,
|
||||||
|
long timeout,
|
||||||
|
Span span);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds standard tags to span. {@link Tags#HTTP_URL}, {@link Tags#HTTP_STATUS}, {@link
|
||||||
|
* Tags#HTTP_METHOD} and {@link Tags#COMPONENT}. If an exception during {@link
|
||||||
|
* javax.servlet.Filter#doFilter(ServletRequest, ServletResponse, FilterChain)} is thrown tag
|
||||||
|
* {@link Tags#ERROR} is added and {@link Tags#HTTP_STATUS} not because at this point it is not
|
||||||
|
* known.
|
||||||
|
*/
|
||||||
|
ServletFilterSpanDecorator STANDARD_TAGS =
|
||||||
|
new ServletFilterSpanDecorator() {
|
||||||
|
@Override
|
||||||
|
public void onRequest(final HttpServletRequest httpServletRequest, final Span span) {
|
||||||
|
Tags.COMPONENT.set(span, "java-web-servlet");
|
||||||
|
|
||||||
|
Tags.HTTP_METHOD.set(span, httpServletRequest.getMethod());
|
||||||
|
//without query params
|
||||||
|
Tags.HTTP_URL.set(span, httpServletRequest.getRequestURL().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponse(
|
||||||
|
final HttpServletRequest httpServletRequest,
|
||||||
|
final HttpServletResponse httpServletResponse,
|
||||||
|
final Span span) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(
|
||||||
|
final HttpServletRequest httpServletRequest,
|
||||||
|
final HttpServletResponse httpServletResponse,
|
||||||
|
final Throwable exception,
|
||||||
|
final Span span) {
|
||||||
|
Tags.ERROR.set(span, Boolean.TRUE);
|
||||||
|
span.log(logsForException(exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTimeout(
|
||||||
|
final HttpServletRequest httpServletRequest,
|
||||||
|
final HttpServletResponse httpServletResponse,
|
||||||
|
final long timeout,
|
||||||
|
final Span span) {
|
||||||
|
Tags.ERROR.set(span, Boolean.TRUE);
|
||||||
|
|
||||||
|
final Map<String, Object> timeoutLogs = new HashMap<>();
|
||||||
|
timeoutLogs.put("event", Tags.ERROR.getKey());
|
||||||
|
timeoutLogs.put("message", "timeout");
|
||||||
|
timeoutLogs.put("timeout", timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> logsForException(final Throwable throwable) {
|
||||||
|
final Map<String, String> errorLog = new HashMap<>(3);
|
||||||
|
errorLog.put("event", Tags.ERROR.getKey());
|
||||||
|
|
||||||
|
final String message =
|
||||||
|
throwable.getCause() != null
|
||||||
|
? throwable.getCause().getMessage()
|
||||||
|
: throwable.getMessage();
|
||||||
|
if (message != null) {
|
||||||
|
errorLog.put("message", message);
|
||||||
|
}
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
throwable.printStackTrace(new PrintWriter(sw));
|
||||||
|
errorLog.put("stack", sw.toString());
|
||||||
|
|
||||||
|
return errorLog;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
import datadog.opentracing.DDSpan
|
||||||
|
import datadog.opentracing.DDTracer
|
||||||
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
|
import datadog.trace.api.DDSpanTypes
|
||||||
|
import datadog.trace.common.writer.ListWriter
|
||||||
|
import io.opentracing.util.GlobalTracer
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import org.eclipse.jetty.server.Server
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||||
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
class JettyServletTest extends AgentTestRunner {
|
||||||
|
|
||||||
|
static final int PORT = randomOpenPort()
|
||||||
|
|
||||||
|
// Jetty needs this to ensure consistent ordering for async.
|
||||||
|
static CountDownLatch latch
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
.addNetworkInterceptor(new Interceptor() {
|
||||||
|
@Override
|
||||||
|
Response intercept(Interceptor.Chain chain) throws IOException {
|
||||||
|
def response = chain.proceed(chain.request())
|
||||||
|
JettyServletTest.latch.await(10, TimeUnit.SECONDS) // don't block forever or test never fails.
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Uncomment when debugging:
|
||||||
|
.connectTimeout(1, TimeUnit.HOURS)
|
||||||
|
.writeTimeout(1, TimeUnit.HOURS)
|
||||||
|
.readTimeout(1, TimeUnit.HOURS)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
private Server jettyServer
|
||||||
|
private ServletContextHandler servletContext
|
||||||
|
|
||||||
|
ListWriter writer = new ListWriter() {
|
||||||
|
@Override
|
||||||
|
void write(final List<DDSpan> trace) {
|
||||||
|
add(trace)
|
||||||
|
JettyServletTest.latch.countDown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DDTracer tracer = new DDTracer(writer)
|
||||||
|
|
||||||
|
def setup() {
|
||||||
|
jettyServer = new Server(PORT)
|
||||||
|
servletContext = new ServletContextHandler()
|
||||||
|
|
||||||
|
servletContext.addServlet(TestServlet.Sync, "/sync")
|
||||||
|
|
||||||
|
jettyServer.setHandler(servletContext)
|
||||||
|
jettyServer.start()
|
||||||
|
|
||||||
|
System.out.println(
|
||||||
|
"Jetty server: http://localhost:" + PORT + "/")
|
||||||
|
|
||||||
|
try {
|
||||||
|
GlobalTracer.register(tracer)
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// Force it anyway using reflection
|
||||||
|
final Field field = GlobalTracer.getDeclaredField("tracer")
|
||||||
|
field.setAccessible(true)
|
||||||
|
field.set(null, tracer)
|
||||||
|
}
|
||||||
|
writer.start()
|
||||||
|
assert GlobalTracer.isRegistered()
|
||||||
|
}
|
||||||
|
|
||||||
|
def cleanup() {
|
||||||
|
jettyServer.stop()
|
||||||
|
jettyServer.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "test #path servlet call"() {
|
||||||
|
setup:
|
||||||
|
latch = new CountDownLatch(1)
|
||||||
|
def request = new Request.Builder()
|
||||||
|
.url("http://localhost:$PORT/$path")
|
||||||
|
.get()
|
||||||
|
.build()
|
||||||
|
def response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
expect:
|
||||||
|
response.body().string().trim() == expectedResponse
|
||||||
|
writer.size() == 2 // second (parent) trace is the okhttp call above...
|
||||||
|
def trace = writer.firstTrace()
|
||||||
|
trace.size() == 1
|
||||||
|
def span = trace[0]
|
||||||
|
|
||||||
|
span.context().operationName == "servlet.request"
|
||||||
|
span.context().spanType == DDSpanTypes.WEB_SERVLET
|
||||||
|
!span.context().getErrorFlag()
|
||||||
|
span.context().parentId != 0 // parent should be the okhttp call.
|
||||||
|
span.context().tags["http.url"] == "http://localhost:$PORT/$path"
|
||||||
|
span.context().tags["http.method"] == "GET"
|
||||||
|
span.context().tags["span.kind"] == "server"
|
||||||
|
span.context().tags["component"] == "java-web-servlet"
|
||||||
|
span.context().tags["http.status_code"] == null // sadly servlet 2.x doesn't expose it generically.
|
||||||
|
span.context().tags["thread.name"] != null
|
||||||
|
span.context().tags["thread.id"] != null
|
||||||
|
span.context().tags.size() == 7
|
||||||
|
|
||||||
|
where:
|
||||||
|
path | expectedResponse
|
||||||
|
"sync" | "Hello Sync"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "test #path error servlet call"() {
|
||||||
|
setup:
|
||||||
|
def request = new Request.Builder()
|
||||||
|
.url("http://localhost:$PORT/$path?error=true")
|
||||||
|
.get()
|
||||||
|
.build()
|
||||||
|
def response = client.newCall(request).execute()
|
||||||
|
|
||||||
|
expect:
|
||||||
|
response.body().string().trim() != expectedResponse
|
||||||
|
writer.size() == 2 // second (parent) trace is the okhttp call above...
|
||||||
|
def trace = writer.firstTrace()
|
||||||
|
trace.size() == 1
|
||||||
|
def span = trace[0]
|
||||||
|
|
||||||
|
span.context().operationName == "servlet.request"
|
||||||
|
span.context().spanType == DDSpanTypes.WEB_SERVLET
|
||||||
|
span.context().getErrorFlag()
|
||||||
|
span.context().parentId != 0 // parent should be the okhttp call.
|
||||||
|
span.context().tags["http.url"] == "http://localhost:$PORT/$path"
|
||||||
|
span.context().tags["http.method"] == "GET"
|
||||||
|
span.context().tags["span.kind"] == "server"
|
||||||
|
span.context().tags["component"] == "java-web-servlet"
|
||||||
|
span.context().tags["http.status_code"] == null // sadly servlet 2.x doesn't expose it generically.
|
||||||
|
span.context().tags["thread.name"] != null
|
||||||
|
span.context().tags["thread.id"] != null
|
||||||
|
span.context().tags["error"] == true
|
||||||
|
span.context().tags["error.msg"] == "some $path error"
|
||||||
|
span.context().tags["error.type"] == RuntimeException.getName()
|
||||||
|
span.context().tags["error.stack"] != null
|
||||||
|
span.context().tags.size() == 11
|
||||||
|
|
||||||
|
where:
|
||||||
|
path | expectedResponse
|
||||||
|
"sync" | "Hello Sync"
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int randomOpenPort() {
|
||||||
|
new ServerSocket(0).withCloseable {
|
||||||
|
it.setReuseAddress(true)
|
||||||
|
return it.getLocalPort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import groovy.servlet.AbstractHttpServlet
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
|
||||||
|
class TestServlet {
|
||||||
|
|
||||||
|
static class Sync extends AbstractHttpServlet {
|
||||||
|
@Override
|
||||||
|
void doGet(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
|
if (req.getParameter("error") != null) {
|
||||||
|
throw new RuntimeException("some sync error")
|
||||||
|
}
|
||||||
|
resp.writer.print("Hello Sync")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,4 +25,13 @@ dependencies {
|
||||||
compile deps.bytebuddy
|
compile deps.bytebuddy
|
||||||
compile deps.opentracing
|
compile deps.opentracing
|
||||||
compile deps.autoservice
|
compile deps.autoservice
|
||||||
|
|
||||||
|
testCompile project(':dd-java-agent:testing')
|
||||||
|
testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '8.2.0.v20160908'
|
||||||
|
testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '8.2.0.v20160908'
|
||||||
|
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '8.0.41'
|
||||||
|
testCompile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-jasper', version: '8.0.41'
|
||||||
|
|
||||||
|
testCompile project(':dd-java-agent:instrumentation:okhttp-3') // used in the tests
|
||||||
|
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package datadog.trace.agent.integration.servlet
|
|
||||||
|
|
||||||
import datadog.opentracing.DDSpan
|
import datadog.opentracing.DDSpan
|
||||||
import datadog.opentracing.DDTracer
|
import datadog.opentracing.DDTracer
|
||||||
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
import datadog.trace.api.DDSpanTypes
|
import datadog.trace.api.DDSpanTypes
|
||||||
import datadog.trace.common.writer.ListWriter
|
import datadog.trace.common.writer.ListWriter
|
||||||
import io.opentracing.util.GlobalTracer
|
import io.opentracing.util.GlobalTracer
|
||||||
|
@ -11,21 +10,20 @@ import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.eclipse.jetty.server.Server
|
import org.eclipse.jetty.server.Server
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||||
import spock.lang.Specification
|
|
||||||
import spock.lang.Unroll
|
import spock.lang.Unroll
|
||||||
|
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class JettyServletTest extends Specification {
|
class JettyServletTest extends AgentTestRunner {
|
||||||
|
|
||||||
static final int PORT = randomOpenPort()
|
static final int PORT = randomOpenPort()
|
||||||
|
|
||||||
// Jetty needs this to ensure consistent ordering for async.
|
// Jetty needs this to ensure consistent ordering for async.
|
||||||
static CountDownLatch latch
|
static CountDownLatch latch
|
||||||
OkHttpClient client = new OkHttpClient.Builder()
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
.addNetworkInterceptor(new Interceptor() {
|
.addNetworkInterceptor(new Interceptor() {
|
||||||
@Override
|
@Override
|
||||||
Response intercept(Interceptor.Chain chain) throws IOException {
|
Response intercept(Interceptor.Chain chain) throws IOException {
|
||||||
def response = chain.proceed(chain.request())
|
def response = chain.proceed(chain.request())
|
||||||
|
@ -151,9 +149,9 @@ class JettyServletTest extends Specification {
|
||||||
span.context().tags.size() == 12
|
span.context().tags.size() == 12
|
||||||
|
|
||||||
where:
|
where:
|
||||||
path | expectedResponse
|
path | expectedResponse
|
||||||
//"async" | "Hello Async" // FIXME: I can't seem get the async error handler to trigger
|
//"async" | "Hello Async" // FIXME: I can't seem get the async error handler to trigger
|
||||||
"sync" | "Hello Sync"
|
"sync" | "Hello Sync"
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int randomOpenPort() {
|
private static int randomOpenPort() {
|
|
@ -1,5 +1,3 @@
|
||||||
package datadog.trace.agent.integration.servlet
|
|
||||||
|
|
||||||
import groovy.servlet.AbstractHttpServlet
|
import groovy.servlet.AbstractHttpServlet
|
||||||
|
|
||||||
import javax.servlet.annotation.WebServlet
|
import javax.servlet.annotation.WebServlet
|
|
@ -1,7 +1,6 @@
|
||||||
package datadog.trace.agent.integration.servlet
|
|
||||||
|
|
||||||
import com.google.common.io.Files
|
import com.google.common.io.Files
|
||||||
import datadog.opentracing.DDTracer
|
import datadog.opentracing.DDTracer
|
||||||
|
import datadog.trace.agent.test.AgentTestRunner
|
||||||
import datadog.trace.api.DDSpanTypes
|
import datadog.trace.api.DDSpanTypes
|
||||||
import datadog.trace.common.writer.ListWriter
|
import datadog.trace.common.writer.ListWriter
|
||||||
import io.opentracing.util.GlobalTracer
|
import io.opentracing.util.GlobalTracer
|
||||||
|
@ -11,12 +10,11 @@ import org.apache.catalina.Context
|
||||||
import org.apache.catalina.startup.Tomcat
|
import org.apache.catalina.startup.Tomcat
|
||||||
import org.apache.tomcat.JarScanFilter
|
import org.apache.tomcat.JarScanFilter
|
||||||
import org.apache.tomcat.JarScanType
|
import org.apache.tomcat.JarScanType
|
||||||
import spock.lang.Specification
|
|
||||||
import spock.lang.Unroll
|
import spock.lang.Unroll
|
||||||
|
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
class TomcatServletTest extends Specification {
|
class TomcatServletTest extends AgentTestRunner {
|
||||||
|
|
||||||
static final int PORT = randomOpenPort()
|
static final int PORT = randomOpenPort()
|
||||||
OkHttpClient client = new OkHttpClient.Builder()
|
OkHttpClient client = new OkHttpClient.Builder()
|
|
@ -18,9 +18,15 @@ public class DDAdvice extends AgentBuilder.Transformer.ForAdvice {
|
||||||
* @return the bytebuddy advice
|
* @return the bytebuddy advice
|
||||||
*/
|
*/
|
||||||
public static AgentBuilder.Transformer.ForAdvice create() {
|
public static AgentBuilder.Transformer.ForAdvice create() {
|
||||||
return new DDAdvice()
|
return create(true);
|
||||||
.with(AGENT_CLASS_LOCATION_STRATEGY)
|
}
|
||||||
.withExceptionHandler(ExceptionHandlers.defaultExceptionHandler());
|
|
||||||
|
public static AgentBuilder.Transformer.ForAdvice create(final boolean includeExceptionHandler) {
|
||||||
|
ForAdvice advice = new DDAdvice().with(AGENT_CLASS_LOCATION_STRATEGY);
|
||||||
|
if (includeExceptionHandler) {
|
||||||
|
advice = advice.withExceptionHandler(ExceptionHandlers.defaultExceptionHandler());
|
||||||
|
}
|
||||||
|
return advice;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DDAdvice() {}
|
private DDAdvice() {}
|
||||||
|
|
Loading…
Reference in New Issue