Merge pull request #135 from DataDog/tyler/servlet
Replace tomcat/jetty specific integ with generic servlet integ.
This commit is contained in:
commit
897b3426b1
26
README.md
26
README.md
|
@ -64,24 +64,24 @@ Finally, add the following JVM argument when starting your application—in your
|
||||||
|
|
||||||
The Java Agent—once passed to your application—automatically traces requests to the frameworks, application servers, and databases shown below. It does this by using various libraries from [opentracing-contrib](https://github.com/opentracing-contrib). In most cases you don't need to install or configure anything; traces will automatically show up in your Datadog dashboards. The exception is [any database library that uses JDBC](#jdbc).
|
The Java Agent—once passed to your application—automatically traces requests to the frameworks, application servers, and databases shown below. It does this by using various libraries from [opentracing-contrib](https://github.com/opentracing-contrib). In most cases you don't need to install or configure anything; traces will automatically show up in your Datadog dashboards. The exception is [any database library that uses JDBC](#jdbc).
|
||||||
|
|
||||||
#### Frameworks
|
|
||||||
|
|
||||||
| Framework | Versions | Comments |
|
|
||||||
| ------------- |:-------------:| ----- |
|
|
||||||
| [OkHTTP](https://github.com/opentracing-contrib/java-okhttp) | 3.x | HTTP client calls with [cross-process](http://opentracing.io/documentation/pages/api/cross-process-tracing.html) headers |
|
|
||||||
| [Apache HTTP Client](https://github.com/opentracing-contrib/java-apache-httpclient) | 4.3 + | HTTP client calls with [cross-process](http://opentracing.io/documentation/pages/api/cross-process-tracing.html) headers|
|
|
||||||
| [AWS SDK](https://github.com/opentracing-contrib/java-aws-sdk) | 1.11.0+ | Trace all client calls to any AWS service |
|
|
||||||
| [Web Servlet Filters](https://github.com/opentracing-contrib/java-web-servlet-filter) | Depends on web server | See [Application Servers](#application-servers) |
|
|
||||||
| [JMS 2](https://github.com/opentracing-contrib/java-jms) | 2.x | Trace calls to message brokers; distributed trace propagation not yet supported |
|
|
||||||
|
|
||||||
#### Application Servers
|
#### Application Servers
|
||||||
|
|
||||||
| Server | Versions | Comments |
|
| Server | Versions | Comments |
|
||||||
| ------------- |:-------------:| -----|
|
| ------------- |:-------------:| -----|
|
||||||
| Jetty | 8.x, 9.x | HTTP client calls with [cross-process](http://opentracing.io/documentation/pages/api/cross-process-tracing.html) headers |
|
| Java Servlet Compatible | 2.3+, 3.0+ | HTTP client calls with [cross-process](http://opentracing.io/documentation/pages/api/cross-process-tracing.html) headers are linked |
|
||||||
| Tomcat | 8.0.x, 8.5.x & 9.x | HTTP client calls with [cross-process](http://opentracing.io/documentation/pages/api/cross-process-tracing.html) headers |
|
|
||||||
|
|
||||||
Requests to any web frameworks that use these application servers—Dropwizard and Spring Boot, for example—are automatically traced as well.
|
*Note:* Many application servers are Servlet compatible such as Tomcat, Jetty, Websphere, Weblogic, etc.
|
||||||
|
Also, frameworks like Spring Boot and Dropwizard inherently work because they use a Servlet compatible embedded application server.
|
||||||
|
|
||||||
|
#### Frameworks
|
||||||
|
|
||||||
|
| Framework | Versions | Comments |
|
||||||
|
| ------------- |:-------------:| ----- |
|
||||||
|
| [OkHTTP](https://github.com/opentracing-contrib/java-okhttp) | 3.x | HTTP client calls with [cross-process](http://opentracing.io/documentation/pages/api/cross-process-tracing.html) headers are linked |
|
||||||
|
| [Apache HTTP Client](https://github.com/opentracing-contrib/java-apache-httpclient) | 4.3 + | HTTP client calls with [cross-process](http://opentracing.io/documentation/pages/api/cross-process-tracing.html) headers are linked|
|
||||||
|
| [AWS SDK](https://github.com/opentracing-contrib/java-aws-sdk) | 1.11.0+ | Trace all client calls to any AWS service |
|
||||||
|
| [Web Servlet Filters](https://github.com/opentracing-contrib/java-web-servlet-filter) | Depends on web server | See [Application Servers](#application-servers) |
|
||||||
|
| [JMS 2](https://github.com/opentracing-contrib/java-jms) | 2.x | Trace calls to message brokers; distributed trace propagation not yet supported |
|
||||||
|
|
||||||
#### Databases
|
#### Databases
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
package com.datadoghq.agent.integration.servlet
|
||||||
|
|
||||||
|
import com.datadoghq.trace.DDBaseSpan
|
||||||
|
import com.datadoghq.trace.DDTags
|
||||||
|
import com.datadoghq.trace.DDTracer
|
||||||
|
import com.datadoghq.trace.writer.ListWriter
|
||||||
|
import io.opentracing.tag.Tags
|
||||||
|
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.Specification
|
||||||
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
import java.util.concurrent.CountDownLatch
|
||||||
|
|
||||||
|
class JettyServletTest extends Specification {
|
||||||
|
|
||||||
|
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()
|
||||||
|
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<DDBaseSpan<?>> 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")
|
||||||
|
servletContext.addServlet(TestServlet.Async, "/async")
|
||||||
|
|
||||||
|
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().getErrorFlag()
|
||||||
|
span.context().parentId != 0 // parent should be the okhttp call.
|
||||||
|
span.context().tags[Tags.HTTP_URL.key] == "http://localhost:$PORT/$path"
|
||||||
|
span.context().tags[Tags.HTTP_METHOD.key] == "GET"
|
||||||
|
span.context().tags[Tags.SPAN_KIND.key] == Tags.SPAN_KIND_SERVER
|
||||||
|
span.context().tags[Tags.COMPONENT.key] == "java-web-servlet"
|
||||||
|
span.context().tags[Tags.HTTP_STATUS.key] == 200
|
||||||
|
span.context().tags[DDTags.THREAD_NAME] != null
|
||||||
|
span.context().tags[DDTags.THREAD_ID] != null
|
||||||
|
span.context().tags.size() == 7
|
||||||
|
|
||||||
|
where:
|
||||||
|
path | expectedResponse
|
||||||
|
"async" | "Hello Async"
|
||||||
|
"sync" | "Hello Sync"
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int randomOpenPort() {
|
||||||
|
new ServerSocket(0).withCloseable {
|
||||||
|
it.setReuseAddress(true)
|
||||||
|
return it.getLocalPort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.datadoghq.agent.integration.servlet
|
||||||
|
|
||||||
|
import groovy.servlet.AbstractHttpServlet
|
||||||
|
|
||||||
|
import javax.servlet.annotation.WebServlet
|
||||||
|
import javax.servlet.http.HttpServletRequest
|
||||||
|
import javax.servlet.http.HttpServletResponse
|
||||||
|
|
||||||
|
class TestServlet {
|
||||||
|
|
||||||
|
@WebServlet
|
||||||
|
static class Sync extends AbstractHttpServlet {
|
||||||
|
@Override
|
||||||
|
void doGet(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
|
resp.writer.print("Hello Sync")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@WebServlet(asyncSupported = true)
|
||||||
|
static class Async extends AbstractHttpServlet {
|
||||||
|
@Override
|
||||||
|
void doGet(HttpServletRequest req, HttpServletResponse resp) {
|
||||||
|
Thread initialThread = Thread.currentThread()
|
||||||
|
def context = req.startAsync()
|
||||||
|
context.start {
|
||||||
|
assert Thread.currentThread() != initialThread
|
||||||
|
resp.writer.print("Hello Async")
|
||||||
|
context.complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package com.datadoghq.agent.integration.servlet
|
||||||
|
|
||||||
|
import com.datadoghq.trace.DDTags
|
||||||
|
import com.datadoghq.trace.DDTracer
|
||||||
|
import com.datadoghq.trace.writer.ListWriter
|
||||||
|
import com.google.common.io.Files
|
||||||
|
import io.opentracing.tag.Tags
|
||||||
|
import io.opentracing.util.GlobalTracer
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import org.apache.catalina.Context
|
||||||
|
import org.apache.catalina.startup.Tomcat
|
||||||
|
import org.apache.tomcat.JarScanFilter
|
||||||
|
import org.apache.tomcat.JarScanType
|
||||||
|
import spock.lang.Specification
|
||||||
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
|
class TomcatServletTest extends Specification {
|
||||||
|
|
||||||
|
static final int PORT = randomOpenPort()
|
||||||
|
OkHttpClient client = new OkHttpClient.Builder()
|
||||||
|
// Uncomment when debugging:
|
||||||
|
// .connectTimeout(1, TimeUnit.HOURS)
|
||||||
|
// .writeTimeout(1, TimeUnit.HOURS)
|
||||||
|
// .readTimeout(1, TimeUnit.HOURS)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
Tomcat tomcatServer
|
||||||
|
Context appContext
|
||||||
|
|
||||||
|
ListWriter writer = new ListWriter()
|
||||||
|
DDTracer tracer = new DDTracer(writer)
|
||||||
|
|
||||||
|
def setup() {
|
||||||
|
tomcatServer = new Tomcat()
|
||||||
|
tomcatServer.setPort(PORT)
|
||||||
|
|
||||||
|
def baseDir = Files.createTempDir()
|
||||||
|
baseDir.deleteOnExit()
|
||||||
|
tomcatServer.setBaseDir(baseDir.getAbsolutePath())
|
||||||
|
|
||||||
|
final File applicationDir = new File(baseDir, "/webapps/ROOT")
|
||||||
|
if (!applicationDir.exists()) {
|
||||||
|
applicationDir.mkdirs()
|
||||||
|
}
|
||||||
|
appContext = tomcatServer.addWebapp("", applicationDir.getAbsolutePath())
|
||||||
|
// Speed up startup by disabling jar scanning:
|
||||||
|
appContext.getJarScanner().setJarScanFilter(new JarScanFilter(){
|
||||||
|
@Override
|
||||||
|
boolean check(JarScanType jarScanType, String jarName) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Tomcat.addServlet(appContext, "syncServlet", new TestServlet.Sync())
|
||||||
|
appContext.addServletMappingDecoded("/sync", "syncServlet")
|
||||||
|
|
||||||
|
Tomcat.addServlet(appContext, "asyncServlet", new TestServlet.Async())
|
||||||
|
appContext.addServletMappingDecoded("/async", "asyncServlet")
|
||||||
|
|
||||||
|
tomcatServer.start()
|
||||||
|
System.out.println(
|
||||||
|
"Tomcat server: http://" + tomcatServer.getHost().getName() + ":" + 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() {
|
||||||
|
tomcatServer.stop()
|
||||||
|
tomcatServer.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "test #path servlet call"() {
|
||||||
|
setup:
|
||||||
|
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().getErrorFlag()
|
||||||
|
span.context().parentId != 0 // parent should be the okhttp call.
|
||||||
|
span.context().tags[Tags.HTTP_URL.key] == "http://localhost:$PORT/$path"
|
||||||
|
span.context().tags[Tags.HTTP_METHOD.key] == "GET"
|
||||||
|
span.context().tags[Tags.SPAN_KIND.key] == Tags.SPAN_KIND_SERVER
|
||||||
|
span.context().tags[Tags.COMPONENT.key] == "java-web-servlet"
|
||||||
|
span.context().tags[Tags.HTTP_STATUS.key] == 200
|
||||||
|
span.context().tags[DDTags.THREAD_NAME] != null
|
||||||
|
span.context().tags[DDTags.THREAD_ID] != null
|
||||||
|
span.context().tags.size() == 7
|
||||||
|
|
||||||
|
where:
|
||||||
|
path | expectedResponse
|
||||||
|
"async" | "Hello Async"
|
||||||
|
"sync" | "Hello Sync"
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int randomOpenPort() {
|
||||||
|
new ServerSocket(0).withCloseable {
|
||||||
|
it.setReuseAddress(true)
|
||||||
|
return it.getLocalPort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,7 +22,7 @@ public class TraceAnnotationsManagerTest {
|
||||||
try {
|
try {
|
||||||
GlobalTracer.register(tracer);
|
GlobalTracer.register(tracer);
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
// Force it anyway using reflexion
|
// Force it anyway using reflection
|
||||||
final Field field = GlobalTracer.class.getDeclaredField("tracer");
|
final Field field = GlobalTracer.class.getDeclaredField("tracer");
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
field.set(null, tracer);
|
field.set(null, tracer);
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
package com.datadoghq.agent.integration;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.eclipse.jetty.server.Server;
|
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/** @author renaudboutet */
|
|
||||||
public class JettyServletInstrumentationTest {
|
|
||||||
|
|
||||||
private Server jettyServer;
|
|
||||||
private ServletContextHandler servletContext;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void beforeTest() throws Exception {
|
|
||||||
servletContext = new ServletContextHandler();
|
|
||||||
servletContext.setContextPath("/");
|
|
||||||
// servletContext.addServlet(TestServlet.class, "/hello");
|
|
||||||
|
|
||||||
jettyServer = new Server(0);
|
|
||||||
jettyServer.setHandler(servletContext);
|
|
||||||
jettyServer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIsTracingFilterPresent() throws IOException {
|
|
||||||
assertThat(servletContext.getServletContext().getFilterRegistration("tracingFilter"))
|
|
||||||
.isNotNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void afterTest() throws Exception {
|
|
||||||
jettyServer.stop();
|
|
||||||
jettyServer.join();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
package com.datadoghq.agent.integration;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import org.apache.catalina.Context;
|
|
||||||
import org.apache.catalina.startup.Tomcat;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class TomcatServletInstrumentationTest {
|
|
||||||
|
|
||||||
private final int serverPort = 9786;
|
|
||||||
|
|
||||||
protected Tomcat tomcatServer;
|
|
||||||
Context appContext;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void beforeTest() throws Exception {
|
|
||||||
tomcatServer = new Tomcat();
|
|
||||||
tomcatServer.setPort(serverPort);
|
|
||||||
|
|
||||||
final File baseDir = new File("tomcat");
|
|
||||||
tomcatServer.setBaseDir(baseDir.getAbsolutePath());
|
|
||||||
|
|
||||||
final File applicationDir = new File(baseDir + "/webapps", "/ROOT");
|
|
||||||
if (!applicationDir.exists()) {
|
|
||||||
applicationDir.mkdirs();
|
|
||||||
}
|
|
||||||
appContext = tomcatServer.addWebapp("", applicationDir.getAbsolutePath());
|
|
||||||
// Tomcat.addServlet(appContext, "helloWorldServlet", new TestServlet());
|
|
||||||
// appContext.addServletMappingDecoded("/hello", "helloWorldServlet");
|
|
||||||
|
|
||||||
tomcatServer.start();
|
|
||||||
System.out.println(
|
|
||||||
"Tomcat server: http://" + tomcatServer.getHost().getName() + ":" + serverPort + "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void test() {
|
|
||||||
assertThat(appContext.getServletContext().getFilterRegistration("tracingFilter")).isNotNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void afterTest() throws Exception {
|
|
||||||
tomcatServer.stop();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,10 +22,8 @@ dependencies {
|
||||||
compile group: 'io.opentracing.contrib', name: 'opentracing-cassandra-driver', version: '0.0.2'
|
compile group: 'io.opentracing.contrib', name: 'opentracing-cassandra-driver', version: '0.0.2'
|
||||||
compile group: 'io.opentracing.contrib', name: 'opentracing-apache-httpclient', version: '0.0.2'
|
compile group: 'io.opentracing.contrib', name: 'opentracing-apache-httpclient', version: '0.0.2'
|
||||||
|
|
||||||
compileOnly group: 'org.eclipse.jetty', name: 'jetty-util', version: '9.3.6.v20151106'
|
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
|
||||||
compileOnly group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.3.6.v20151106'
|
// compileOnly group: 'javax.servlet', name: 'servlet-api', version: '2.3'
|
||||||
compileOnly group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.3.6.v20151106'
|
|
||||||
compileOnly group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '9.0.0.M1'
|
|
||||||
compileOnly group: 'org.mongodb', name: 'mongo-java-driver', version: '3.4.2'
|
compileOnly group: 'org.mongodb', name: 'mongo-java-driver', version: '3.4.2'
|
||||||
compileOnly group: 'org.mongodb', name: 'mongodb-driver-async', version: '3.4.2'
|
compileOnly group: 'org.mongodb', name: 'mongodb-driver-async', version: '3.4.2'
|
||||||
compileOnly group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
|
compileOnly group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
package com.datadoghq.agent.integration;
|
|
||||||
|
|
||||||
import io.opentracing.contrib.web.servlet.filter.TracingFilter;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import javax.servlet.Filter;
|
|
||||||
import javax.servlet.FilterRegistration;
|
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
|
||||||
import org.jboss.byteman.rule.Rule;
|
|
||||||
|
|
||||||
/** Patch the Jetty Servlet during the init steps */
|
|
||||||
public class JettyServletHelper extends DDAgentTracingHelper<ServletContextHandler> {
|
|
||||||
|
|
||||||
private static final String pattern = "/*";
|
|
||||||
|
|
||||||
public JettyServletHelper(final Rule rule) {
|
|
||||||
super(rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strategy: Use the contextHandler provided to add a new Tracing filter
|
|
||||||
*
|
|
||||||
* @param contextHandler The current contextHandler
|
|
||||||
* @return The same current contextHandler but patched
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected ServletContextHandler doPatch(final ServletContextHandler contextHandler)
|
|
||||||
throws Exception {
|
|
||||||
if (contextHandler.getServletContext().getFilterRegistration("tracingFilter") == null) {
|
|
||||||
final Filter filter = new TracingFilter(tracer);
|
|
||||||
final FilterRegistration.Dynamic registration =
|
|
||||||
contextHandler.getServletContext().addFilter("tracingFilter", filter);
|
|
||||||
if (registration != null) { // filter of that name must already be registered.
|
|
||||||
registration.setAsyncSupported(true);
|
|
||||||
registration.addMappingForUrlPatterns(
|
|
||||||
EnumSet.allOf(javax.servlet.DispatcherType.class), true, pattern);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contextHandler;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.datadoghq.agent.integration;
|
||||||
|
|
||||||
|
import io.opentracing.ActiveSpan;
|
||||||
|
import io.opentracing.NoopTracerFactory;
|
||||||
|
import io.opentracing.SpanContext;
|
||||||
|
import io.opentracing.Tracer;
|
||||||
|
import io.opentracing.contrib.web.servlet.filter.HttpServletRequestExtractAdapter;
|
||||||
|
import io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator;
|
||||||
|
import io.opentracing.propagation.Format;
|
||||||
|
import io.opentracing.tag.Tags;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jboss.byteman.rule.Rule;
|
||||||
|
|
||||||
|
/** Please be very careful not to introduce any Servlet 3 dependencies into this class. */
|
||||||
|
@Slf4j
|
||||||
|
public class Servlet2Helper extends OpenTracingHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as a key of {@link HttpServletRequest#setAttribute(String, Object)} to inject server span
|
||||||
|
* context
|
||||||
|
*/
|
||||||
|
public static final String SERVER_SPAN_CONTEXT =
|
||||||
|
Servlet2Helper.class.getName() + ".activeSpanContext";
|
||||||
|
|
||||||
|
public static final String SERVLET_OPERATION_NAME = "servlet.request";
|
||||||
|
|
||||||
|
protected final Tracer tracer;
|
||||||
|
|
||||||
|
public Servlet2Helper(final Rule rule) {
|
||||||
|
super(rule);
|
||||||
|
Tracer tracerResolved;
|
||||||
|
try {
|
||||||
|
tracerResolved = getTracer();
|
||||||
|
tracerResolved = tracerResolved == null ? NoopTracerFactory.create() : tracerResolved;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
tracerResolved = NoopTracerFactory.create();
|
||||||
|
log.warn("Failed to retrieve the tracer, using a NoopTracer instead: {}", e.getMessage());
|
||||||
|
log.warn(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
tracer = tracerResolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRequest(final HttpServletRequest req, final HttpServletResponse resp) {
|
||||||
|
if (req.getAttribute(SERVER_SPAN_CONTEXT) != null) {
|
||||||
|
// Perhaps we're already tracing?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SpanContext extractedContext =
|
||||||
|
tracer.extract(Format.Builtin.HTTP_HEADERS, new HttpServletRequestExtractAdapter(req));
|
||||||
|
|
||||||
|
final ActiveSpan span =
|
||||||
|
tracer
|
||||||
|
.buildSpan(SERVLET_OPERATION_NAME)
|
||||||
|
.asChildOf(extractedContext)
|
||||||
|
.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER)
|
||||||
|
.startActive();
|
||||||
|
|
||||||
|
req.setAttribute(SERVER_SPAN_CONTEXT, span.context());
|
||||||
|
|
||||||
|
ServletFilterSpanDecorator.STANDARD_TAGS.onRequest(req, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onError(
|
||||||
|
final HttpServletRequest req, final HttpServletResponse resp, final Throwable ex) {
|
||||||
|
if (req.getAttribute(SERVER_SPAN_CONTEXT) == null) {
|
||||||
|
// Doesn't look like an active span was started at the beginning
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ActiveSpan span = tracer.activeSpan();
|
||||||
|
ServletFilterSpanDecorator.STANDARD_TAGS.onError(req, resp, ex, span);
|
||||||
|
span.deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResponse(final HttpServletRequest req, final HttpServletResponse resp) {
|
||||||
|
if (req.getAttribute(SERVER_SPAN_CONTEXT) == null) {
|
||||||
|
// Doesn't look like an active span was started at the beginning
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ActiveSpan span = tracer.activeSpan();
|
||||||
|
ServletFilterSpanDecorator.STANDARD_TAGS.onResponse(req, resp, span);
|
||||||
|
span.deactivate();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
package com.datadoghq.agent.integration;
|
||||||
|
|
||||||
|
import io.opentracing.ActiveSpan;
|
||||||
|
import io.opentracing.contrib.web.servlet.filter.ServletFilterSpanDecorator;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import javax.servlet.AsyncEvent;
|
||||||
|
import javax.servlet.AsyncListener;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.jboss.byteman.rule.Rule;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class Servlet3Helper extends Servlet2Helper {
|
||||||
|
|
||||||
|
public Servlet3Helper(final Rule rule) {
|
||||||
|
super(rule);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The distinction with this method compared with Servlet2Helper.onResponse is the addition of the
|
||||||
|
* async support.
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* @param resp
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onResponse(final HttpServletRequest req, final HttpServletResponse resp) {
|
||||||
|
if (req.getAttribute(SERVER_SPAN_CONTEXT) == null) {
|
||||||
|
// Doesn't look like an active span was started at the beginning
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ActiveSpan span = tracer.activeSpan();
|
||||||
|
if (req.isAsyncStarted()) {
|
||||||
|
addAsyncListeners(req, resp, span);
|
||||||
|
} else {
|
||||||
|
ServletFilterSpanDecorator.STANDARD_TAGS.onResponse(req, resp, span);
|
||||||
|
}
|
||||||
|
span.deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAsyncListeners(
|
||||||
|
final HttpServletRequest req, final HttpServletResponse resp, final ActiveSpan span) {
|
||||||
|
|
||||||
|
final ActiveSpan.Continuation cont = span.capture();
|
||||||
|
final AtomicBoolean activated = new AtomicBoolean(false);
|
||||||
|
// what if async is already finished? This would not be called
|
||||||
|
req.getAsyncContext()
|
||||||
|
.addListener(
|
||||||
|
new AsyncListener() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(final AsyncEvent event) throws IOException {
|
||||||
|
if (activated.compareAndSet(false, true)) {
|
||||||
|
try (ActiveSpan activeSpan = cont.activate()) {
|
||||||
|
ServletFilterSpanDecorator.STANDARD_TAGS.onResponse(
|
||||||
|
(HttpServletRequest) event.getSuppliedRequest(),
|
||||||
|
(HttpServletResponse) event.getSuppliedResponse(),
|
||||||
|
span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTimeout(final AsyncEvent event) throws IOException {
|
||||||
|
if (activated.compareAndSet(false, true)) {
|
||||||
|
try (ActiveSpan activeSpan = cont.activate()) {
|
||||||
|
ServletFilterSpanDecorator.STANDARD_TAGS.onTimeout(
|
||||||
|
(HttpServletRequest) event.getSuppliedRequest(),
|
||||||
|
(HttpServletResponse) event.getSuppliedResponse(),
|
||||||
|
event.getAsyncContext().getTimeout(),
|
||||||
|
span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(final AsyncEvent event) throws IOException {
|
||||||
|
if (activated.compareAndSet(false, true)) {
|
||||||
|
try (ActiveSpan activeSpan = cont.activate()) {
|
||||||
|
ServletFilterSpanDecorator.STANDARD_TAGS.onError(
|
||||||
|
(HttpServletRequest) event.getSuppliedRequest(),
|
||||||
|
(HttpServletResponse) event.getSuppliedResponse(),
|
||||||
|
event.getThrowable(),
|
||||||
|
span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartAsync(final AsyncEvent event) throws IOException {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,40 +0,0 @@
|
||||||
package com.datadoghq.agent.integration;
|
|
||||||
|
|
||||||
import io.opentracing.contrib.web.servlet.filter.TracingFilter;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import javax.servlet.Filter;
|
|
||||||
import javax.servlet.FilterRegistration;
|
|
||||||
import org.apache.catalina.core.ApplicationContext;
|
|
||||||
import org.jboss.byteman.rule.Rule;
|
|
||||||
|
|
||||||
/** Patch the Tomcat Servlet during the init steps */
|
|
||||||
public class TomcatServletHelper extends DDAgentTracingHelper<ApplicationContext> {
|
|
||||||
|
|
||||||
private static final String pattern = "/*";
|
|
||||||
|
|
||||||
public TomcatServletHelper(final Rule rule) {
|
|
||||||
super(rule);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strategy: Use the contextHandler provided to add a new Tracing filter
|
|
||||||
*
|
|
||||||
* @param contextHandler The current contextHandler
|
|
||||||
* @return The same current contextHandler but patched
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected ApplicationContext doPatch(final ApplicationContext contextHandler) throws Exception {
|
|
||||||
if (contextHandler.getFilterRegistration("tracingFilter") == null) {
|
|
||||||
final Filter filter = new TracingFilter(tracer);
|
|
||||||
final FilterRegistration.Dynamic registration =
|
|
||||||
contextHandler.addFilter("tracingFilter", filter);
|
|
||||||
if (registration != null) { // filter of that name must already be registered.
|
|
||||||
registration.setAsyncSupported(true);
|
|
||||||
registration.addMappingForUrlPatterns(
|
|
||||||
EnumSet.allOf(javax.servlet.DispatcherType.class), true, pattern);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return contextHandler;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
apply plugin: 'version-scan'
|
|
||||||
|
|
||||||
versionScan {
|
|
||||||
group = "org.eclipse.jetty"
|
|
||||||
module = "jetty-server"
|
|
||||||
versions = "[8.0,)"
|
|
||||||
legacyGroup = "org.mortbay.jetty"
|
|
||||||
legacyModule = "jetty"
|
|
||||||
scanMethods = true
|
|
||||||
verifyPresent = [
|
|
||||||
"org.eclipse.jetty.server.ServletRequestHttpWrapper": "getPart",
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
apply plugin: 'version-scan'
|
||||||
|
|
||||||
|
versionScan {
|
||||||
|
group = "javax.servlet"
|
||||||
|
module = "servlet-api"
|
||||||
|
versions = "[2.3,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"javax.servlet.ServletContextEvent": null,
|
||||||
|
"javax.servlet.FilterChain" : null,
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
apply plugin: 'version-scan'
|
||||||
|
|
||||||
|
versionScan {
|
||||||
|
group = "javax.servlet"
|
||||||
|
module = 'javax.servlet-api'
|
||||||
|
legacyModule = "servlet-api"
|
||||||
|
versions = "[3.0,)"
|
||||||
|
verifyPresent = [
|
||||||
|
"javax.servlet.AsyncEvent" : null,
|
||||||
|
"javax.servlet.AsyncListener": null,
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
apply plugin: 'version-scan'
|
|
||||||
|
|
||||||
versionScan {
|
|
||||||
group = "org.apache.tomcat.embed"
|
|
||||||
module = "tomcat-embed-core"
|
|
||||||
versions = "[8.0,)"
|
|
||||||
verifyPresent = [
|
|
||||||
"org.apache.catalina.WebResource" : null,
|
|
||||||
"org.apache.catalina.webresources.TrackedInputStream" : null,
|
|
||||||
"org.apache.catalina.webresources.AbstractArchiveResource": null,
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
apply plugin: 'version-scan'
|
|
||||||
|
|
||||||
versionScan {
|
|
||||||
group = "org.apache.tomcat"
|
|
||||||
module = "tomcat-catalina"
|
|
||||||
versions = "[8.0,)"
|
|
||||||
verifyPresent = [
|
|
||||||
"org.apache.catalina.WebResource" : null,
|
|
||||||
"org.apache.catalina.webresources.TrackedInputStream" : null,
|
|
||||||
"org.apache.catalina.webresources.AbstractArchiveResource": null,
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -80,10 +80,10 @@ public class InstrumentationRulesManager {
|
||||||
final ClassLoader cl;
|
final ClassLoader cl;
|
||||||
if (obj instanceof ClassLoader) {
|
if (obj instanceof ClassLoader) {
|
||||||
cl = (ClassLoader) obj;
|
cl = (ClassLoader) obj;
|
||||||
log.info("Calling initialize with {}", cl);
|
log.debug("Calling initialize with {}", cl);
|
||||||
} else {
|
} else {
|
||||||
cl = obj.getClass().getClassLoader();
|
cl = obj.getClass().getClassLoader();
|
||||||
log.info("Calling initialize with {} and classloader ", obj, cl);
|
log.debug("Calling initialize with {} and classloader {}", obj, cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
AgentRulesManager.INSTANCE.instrumentationRulesManager.initialize(cl);
|
AgentRulesManager.INSTANCE.instrumentationRulesManager.initialize(cl);
|
||||||
|
|
|
@ -81,23 +81,43 @@ opentracing-okhttp3:
|
||||||
okhttp3.ConnectionPool:
|
okhttp3.ConnectionPool:
|
||||||
okhttp3.Headers:
|
okhttp3.Headers:
|
||||||
|
|
||||||
opentracing-web-servlet-filter_jetty:
|
httpservlet-2:
|
||||||
- artifact: jetty-server
|
- artifact: HttpServlet-2.service-entry
|
||||||
supported_version: (8\.|9\.).*
|
|
||||||
identifying_present_classes:
|
identifying_present_classes:
|
||||||
org.eclipse.jetty.server.ServletRequestHttpWrapper: getPart
|
javax.servlet.ServletContextEvent:
|
||||||
|
javax.servlet.FilterChain:
|
||||||
|
identifying_missing_classes:
|
||||||
|
- javax.servlet.AsyncEvent
|
||||||
|
- javax.servlet.AsyncListener
|
||||||
|
|
||||||
opentracing-web-servlet-filter_tomcat:
|
- artifact: HttpServlet-2.service-exit
|
||||||
- artifact: opentracing-web-servlet-filter_tomcat
|
|
||||||
supported_version: (8\.|9\.).*
|
|
||||||
identifying_present_classes:
|
identifying_present_classes:
|
||||||
org.apache.catalina.WebResource:
|
javax.servlet.ServletContextEvent:
|
||||||
org.apache.catalina.webresources.TrackedInputStream:
|
javax.servlet.FilterChain:
|
||||||
org.apache.catalina.webresources.AbstractArchiveResource:
|
identifying_missing_classes:
|
||||||
|
- javax.servlet.AsyncEvent
|
||||||
|
- javax.servlet.AsyncListener
|
||||||
|
|
||||||
- artifact: opentracing-web-servlet-filter_tomcat
|
- artifact: HttpServlet-2.service-error
|
||||||
supported_version: (8\.|9\.).*
|
|
||||||
identifying_present_classes:
|
identifying_present_classes:
|
||||||
org.apache.catalina.WebResource:
|
javax.servlet.ServletContextEvent:
|
||||||
org.apache.catalina.webresources.TrackedInputStream:
|
javax.servlet.FilterChain:
|
||||||
org.apache.catalina.webresources.AbstractArchiveResource:
|
identifying_missing_classes:
|
||||||
|
- javax.servlet.AsyncEvent
|
||||||
|
- javax.servlet.AsyncListener
|
||||||
|
|
||||||
|
httpservlet-3:
|
||||||
|
- artifact: HttpServlet-3.service-entry
|
||||||
|
identifying_present_classes:
|
||||||
|
javax.servlet.AsyncEvent:
|
||||||
|
javax.servlet.AsyncListener:
|
||||||
|
|
||||||
|
- artifact: HttpServlet-3.service-exit
|
||||||
|
identifying_present_classes:
|
||||||
|
javax.servlet.AsyncEvent:
|
||||||
|
javax.servlet.AsyncListener:
|
||||||
|
|
||||||
|
- artifact: HttpServlet-3.service-error
|
||||||
|
identifying_present_classes:
|
||||||
|
javax.servlet.AsyncEvent:
|
||||||
|
javax.servlet.AsyncListener:
|
||||||
|
|
|
@ -82,25 +82,13 @@ DO
|
||||||
ENDRULE
|
ENDRULE
|
||||||
|
|
||||||
|
|
||||||
# Instrument Servlet - Jetty
|
# Instrument Servlet
|
||||||
# ===========================
|
# ===========================
|
||||||
RULE ServletContextHandler-clinit
|
RULE HttpServlet-init
|
||||||
CLASS org.eclipse.jetty.servlet.ServletContextHandler
|
CLASS ^javax.servlet.http.HttpServlet
|
||||||
METHOD <clinit>
|
METHOD <init>
|
||||||
AT EXIT
|
AT EXIT
|
||||||
IF TRUE
|
IF TRUE
|
||||||
DO
|
DO
|
||||||
com.datadoghq.agent.InstrumentationRulesManager.registerClassLoad();
|
com.datadoghq.agent.InstrumentationRulesManager.registerClassLoad($0);
|
||||||
ENDRULE
|
|
||||||
|
|
||||||
|
|
||||||
# Instrument Servlet - Tomcat
|
|
||||||
# ===========================
|
|
||||||
RULE ApplicationContext-clinit
|
|
||||||
CLASS org.apache.catalina.core.ApplicationContext
|
|
||||||
METHOD <clinit>
|
|
||||||
AT EXIT
|
|
||||||
IF TRUE
|
|
||||||
DO
|
|
||||||
com.datadoghq.agent.InstrumentationRulesManager.registerClassLoad();
|
|
||||||
ENDRULE
|
ENDRULE
|
||||||
|
|
|
@ -107,31 +107,72 @@ DO
|
||||||
patch($0)
|
patch($0)
|
||||||
ENDRULE
|
ENDRULE
|
||||||
|
|
||||||
|
# Instrument Servlet 2
|
||||||
# Instrument Servlet - Jetty
|
|
||||||
# ===========================
|
# ===========================
|
||||||
# State 0 - no filter installed
|
RULE HttpServlet-2.service-entry
|
||||||
# State 1 - filter installed
|
CLASS ^javax.servlet.http.HttpServlet
|
||||||
RULE opentracing-web-servlet-filter_jetty
|
METHOD service(HttpServletRequest, HttpServletResponse)
|
||||||
CLASS org.eclipse.jetty.servlet.ServletContextHandler
|
HELPER com.datadoghq.agent.integration.Servlet2Helper
|
||||||
METHOD <init>
|
COMPILE
|
||||||
HELPER com.datadoghq.agent.integration.JettyServletHelper
|
AT ENTRY
|
||||||
AT EXIT
|
IF TRUE
|
||||||
IF getState($0.getServletContext()) == 0
|
|
||||||
DO
|
DO
|
||||||
patch($0)
|
onRequest($1, $2)
|
||||||
ENDRULE
|
ENDRULE
|
||||||
|
|
||||||
|
RULE HttpServlet-2.service-exit
|
||||||
# Instrument Servlet - Tomcat
|
CLASS ^javax.servlet.http.HttpServlet
|
||||||
# ===========================
|
METHOD service(HttpServletRequest, HttpServletResponse)
|
||||||
RULE opentracing-web-servlet-filter_tomcat
|
HELPER com.datadoghq.agent.integration.Servlet2Helper
|
||||||
CLASS org.apache.catalina.core.ApplicationContext
|
|
||||||
METHOD <init>
|
|
||||||
COMPILE
|
COMPILE
|
||||||
HELPER com.datadoghq.agent.integration.TomcatServletHelper
|
|
||||||
AT EXIT
|
AT EXIT
|
||||||
IF TRUE
|
IF TRUE
|
||||||
DO
|
DO
|
||||||
patch($0)
|
onResponse($1, $2)
|
||||||
|
ENDRULE
|
||||||
|
|
||||||
|
RULE HttpServlet-2.service-error
|
||||||
|
CLASS ^javax.servlet.http.HttpServlet
|
||||||
|
METHOD service(HttpServletRequest, HttpServletResponse)
|
||||||
|
HELPER com.datadoghq.agent.integration.Servlet2Helper
|
||||||
|
COMPILE
|
||||||
|
AT EXCEPTION EXIT
|
||||||
|
IF TRUE
|
||||||
|
DO
|
||||||
|
onError($1, $2, $^)
|
||||||
|
ENDRULE
|
||||||
|
|
||||||
|
# Instrument Servlet 3
|
||||||
|
# ===========================
|
||||||
|
RULE HttpServlet-3.service-entry
|
||||||
|
CLASS ^javax.servlet.http.HttpServlet
|
||||||
|
METHOD service(HttpServletRequest, HttpServletResponse)
|
||||||
|
HELPER com.datadoghq.agent.integration.Servlet3Helper
|
||||||
|
COMPILE
|
||||||
|
AT ENTRY
|
||||||
|
IF TRUE
|
||||||
|
DO
|
||||||
|
onRequest($1, $2)
|
||||||
|
ENDRULE
|
||||||
|
|
||||||
|
RULE HttpServlet-3.service-exit
|
||||||
|
CLASS ^javax.servlet.http.HttpServlet
|
||||||
|
METHOD service(HttpServletRequest, HttpServletResponse)
|
||||||
|
HELPER com.datadoghq.agent.integration.Servlet3Helper
|
||||||
|
COMPILE
|
||||||
|
AT EXIT
|
||||||
|
IF TRUE
|
||||||
|
DO
|
||||||
|
onResponse($1, $2)
|
||||||
|
ENDRULE
|
||||||
|
|
||||||
|
RULE HttpServlet-3.service-error
|
||||||
|
CLASS ^javax.servlet.http.HttpServlet
|
||||||
|
METHOD service(HttpServletRequest, HttpServletResponse)
|
||||||
|
HELPER com.datadoghq.agent.integration.Servlet3Helper
|
||||||
|
COMPILE
|
||||||
|
AT EXCEPTION EXIT
|
||||||
|
IF TRUE
|
||||||
|
DO
|
||||||
|
onError($1, $2, $^)
|
||||||
ENDRULE
|
ENDRULE
|
||||||
|
|
|
@ -17,8 +17,6 @@ public class OperationDecorator extends AbstractDecorator {
|
||||||
// Component name <> Operation name
|
// Component name <> Operation name
|
||||||
put("apache-httpclient", "apache.http");
|
put("apache-httpclient", "apache.http");
|
||||||
put("java-aws-sdk", "aws.http");
|
put("java-aws-sdk", "aws.http");
|
||||||
// Jetty + Tomcat (same integration used)
|
|
||||||
put("java-web-servlet", "servlet.request");
|
|
||||||
// FIXME: JMS ops card is low (jms-send or jms-receive), may be this mapping is useless
|
// FIXME: JMS ops card is low (jms-send or jms-receive), may be this mapping is useless
|
||||||
put("java-jms", "jms");
|
put("java-jms", "jms");
|
||||||
put("okhttp", "okhttp.http");
|
put("okhttp", "okhttp.http");
|
||||||
|
|
|
@ -15,13 +15,12 @@ include ':dd-java-agent:integrations:helpers'
|
||||||
include ':dd-java-agent:integrations:apache-httpclient'
|
include ':dd-java-agent:integrations:apache-httpclient'
|
||||||
include ':dd-java-agent:integrations:aws-sdk'
|
include ':dd-java-agent:integrations:aws-sdk'
|
||||||
include ':dd-java-agent:integrations:cassandra'
|
include ':dd-java-agent:integrations:cassandra'
|
||||||
include ':dd-java-agent:integrations:jetty'
|
|
||||||
include ':dd-java-agent:integrations:jms'
|
include ':dd-java-agent:integrations:jms'
|
||||||
include ':dd-java-agent:integrations:mongo'
|
include ':dd-java-agent:integrations:mongo'
|
||||||
include ':dd-java-agent:integrations:mongo-async'
|
include ':dd-java-agent:integrations:mongo-async'
|
||||||
include ':dd-java-agent:integrations:okhttp'
|
include ':dd-java-agent:integrations:okhttp'
|
||||||
include ':dd-java-agent:integrations:tomcat'
|
include ':dd-java-agent:integrations:servlet-2'
|
||||||
include ':dd-java-agent:integrations:tomcat-embedded'
|
include ':dd-java-agent:integrations:servlet-3'
|
||||||
|
|
||||||
def setBuildFile(project) {
|
def setBuildFile(project) {
|
||||||
project.buildFileName = "${project.name}.gradle"
|
project.buildFileName = "${project.name}.gradle"
|
||||||
|
|
Loading…
Reference in New Issue