diff --git a/custom/build.gradle.kts b/custom/build.gradle.kts index a224f0adc..91ccd1ee8 100644 --- a/custom/build.gradle.kts +++ b/custom/build.gradle.kts @@ -6,7 +6,7 @@ plugins { val versions: Map by extra dependencies { - implementation(project(":bootstrap")) + compileOnly(project(":bootstrap")) implementation("io.opentelemetry:opentelemetry-sdk:${versions["opentelemetry"]}") implementation("io.opentelemetry:opentelemetry-exporter-jaeger-thrift:${versions["opentelemetry"]}") implementation("io.opentelemetry.javaagent:opentelemetry-javaagent-spi:${versions["opentelemetryJavaagent"]}") diff --git a/instrumentation/build.gradle b/instrumentation/build.gradle index 81f7de2e7..70f640d51 100644 --- a/instrumentation/build.gradle +++ b/instrumentation/build.gradle @@ -18,7 +18,7 @@ subprojects { annotationProcessor("com.google.auto:auto-common:0.8") implementation("com.google.auto.service:auto-service:1.0-rc3") implementation("com.google.auto:auto-common:0.8") - implementation(project(":bootstrap")) + compileOnly(project(":bootstrap")) } compileJava { diff --git a/instrumentation/tomcat/build.gradle b/instrumentation/tomcat/build.gradle new file mode 100644 index 000000000..5867caa72 --- /dev/null +++ b/instrumentation/tomcat/build.gradle @@ -0,0 +1,7 @@ +plugins { + id "java" +} + +dependencies { + compileOnly('org.apache.tomcat:tomcat-catalina:9.0.40') +} \ No newline at end of file diff --git a/instrumentation/tomcat/src/main/java/com/splunk/opentelemetry/middleware/TomcatAttributesInstrumentationModule.java b/instrumentation/tomcat/src/main/java/com/splunk/opentelemetry/middleware/TomcatAttributesInstrumentationModule.java new file mode 100644 index 000000000..12cb86d80 --- /dev/null +++ b/instrumentation/tomcat/src/main/java/com/splunk/opentelemetry/middleware/TomcatAttributesInstrumentationModule.java @@ -0,0 +1,78 @@ +/* + * Copyright Splunk Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.splunk.opentelemetry.middleware; + +import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.isPublic; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import com.google.auto.service.AutoService; +import com.splunk.opentelemetry.javaagent.bootstrap.MiddlewareHolder; +import io.opentelemetry.javaagent.tooling.InstrumentationModule; +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.catalina.util.ServerInfo; + +@AutoService(InstrumentationModule.class) +public class TomcatAttributesInstrumentationModule extends InstrumentationModule { + + public TomcatAttributesInstrumentationModule() { + super("tomcat"); + } + + @Override + public ElementMatcher.Junction classLoaderMatcher() { + return hasClassesNamed( + "org.apache.catalina.startup.Catalina", "org.apache.catalina.util.ServerInfo"); + } + + @Override + public List typeInstrumentations() { + return Collections.singletonList(new Instrumentation()); + } + + public static class Instrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher typeMatcher() { + return named("org.apache.catalina.startup.Catalina"); + } + + @Override + public Map, String> transformers() { + return Collections.singletonMap( + isMethod().and(isPublic()).and(named("start")), + TomcatAttributesInstrumentationModule.class.getName() + "$MiddlewareInitializedAdvice"); + } + } + + @SuppressWarnings("unused") + public static class MiddlewareInitializedAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter() { + MiddlewareHolder.trySetVersion(ServerInfo.getServerNumber()); + MiddlewareHolder.trySetName("tomcat"); + } + } +} diff --git a/matrix/build.gradle.kts b/matrix/build.gradle.kts index daa4ab1de..a1b3ab849 100644 --- a/matrix/build.gradle.kts +++ b/matrix/build.gradle.kts @@ -32,14 +32,14 @@ val buildTestImagesTask = tasks.create("buildTestImages") { val targets = mapOf( "jetty" to mapOf( "9.4" to listOf("8", "11", "15"), - "10.0.0.beta3" to listOf("11", "15"), - "11.0.0.beta3" to listOf("11", "15") + "10.0.0.beta3" to listOf("11", "15") + // "11.0.0.beta3" to listOf("11", "15") TODO - enable when out of beta ), "tomcat" to mapOf( "7" to listOf("8"), "8" to listOf("8", "11"), - "9" to listOf("8", "11"), - "10" to listOf("8", "11") + "9" to listOf("8", "11") + // "10" to listOf("8", "11") TODO - enable when out of beta ), "payara" to mapOf( "5.2020.6" to listOf("8"), diff --git a/settings.gradle.kts b/settings.gradle.kts index 9eab6646d..aae860054 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,5 +14,6 @@ include("agent", "custom", "instrumentation", "instrumentation:jetty", + "instrumentation:tomcat", "smoke-tests", "matrix") \ No newline at end of file diff --git a/smoke-tests/src/test/java/com/splunk/opentelemetry/JettySmokeTest.java b/smoke-tests/src/test/java/com/splunk/opentelemetry/JettySmokeTest.java index 59f063aed..b9bce2361 100644 --- a/smoke-tests/src/test/java/com/splunk/opentelemetry/JettySmokeTest.java +++ b/smoke-tests/src/test/java/com/splunk/opentelemetry/JettySmokeTest.java @@ -40,7 +40,7 @@ private static Stream supportedConfigurations() { arguments("splunk-jetty:10.0.0.beta3-jdk15", JETTY10_SERVER_ATTRIBUTES)); } - @ParameterizedTest + @ParameterizedTest(name = "[{index}] {0}") @MethodSource("supportedConfigurations") void jettySmokeTest(String imageName, ExpectedServerAttributes expectedServerAttributes) throws IOException, InterruptedException { diff --git a/smoke-tests/src/test/java/com/splunk/opentelemetry/TomcatSmokeTest.java b/smoke-tests/src/test/java/com/splunk/opentelemetry/TomcatSmokeTest.java new file mode 100644 index 000000000..369959f1b --- /dev/null +++ b/smoke-tests/src/test/java/com/splunk/opentelemetry/TomcatSmokeTest.java @@ -0,0 +1,63 @@ +/* + * Copyright Splunk Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.splunk.opentelemetry; + +import static org.junit.jupiter.params.provider.Arguments.arguments; + +import java.io.IOException; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class TomcatSmokeTest extends AppServerTest { + + public static final ExpectedServerAttributes TOMCAT7_SERVER_ATTRIBUTES = + new TomcatAttributes("7.0.107.0"); + public static final ExpectedServerAttributes TOMCAT8_SERVER_ATTRIBUTES = + new TomcatAttributes("8.5.60.0"); + public static final ExpectedServerAttributes TOMCAT9_SERVER_ATTRIBUTES = + new TomcatAttributes("9.0.40.0"); + + private static Stream supportedConfigurations() { + return Stream.of( + arguments("splunk-tomcat:7-jdk8", TOMCAT7_SERVER_ATTRIBUTES), + arguments("splunk-tomcat:8-jdk8", TOMCAT8_SERVER_ATTRIBUTES), + arguments("splunk-tomcat:8-jdk11", TOMCAT8_SERVER_ATTRIBUTES), + arguments("splunk-tomcat:9-jdk8", TOMCAT9_SERVER_ATTRIBUTES), + arguments("splunk-tomcat:9-jdk11", TOMCAT9_SERVER_ATTRIBUTES)); + } + + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("supportedConfigurations") + void jettySmokeTest(String imageName, ExpectedServerAttributes expectedServerAttributes) + throws IOException, InterruptedException { + startTarget(imageName); + + assertServerHandler(expectedServerAttributes); + assertWebAppTrace(expectedServerAttributes); + } + + public static class TomcatAttributes extends ExpectedServerAttributes { + public TomcatAttributes(String version) { + super( + "/this-is-definitely-not-there-but-there-should-be-a-trace-nevertheless", + "tomcat", + version); + } + } +}