From 069a8851c7ea5cc2156b97f3ac35273ce06220f6 Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Sun, 9 Nov 2025 09:18:20 -0500 Subject: [PATCH 1/3] jsp tests --- .../instrumentation/jsp/JspInstrumentationBasicTests.java | 3 +-- .../jsp/JspInstrumentationForwardTests.java | 3 +-- .../javaagent/instrumentation/jsp/JspSpanAssertions.java | 8 ++++---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java index f5642eaf4163..9da7fabe6eaf 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java +++ b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java @@ -44,8 +44,7 @@ class JspInstrumentationBasicTests extends AbstractHttpServerUsingTest { @RegisterExtension - public static final InstrumentationExtension testing = - HttpServerInstrumentationExtension.forAgent(); + static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent(); private static JspSpanAssertions spanAsserts; diff --git a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationForwardTests.java b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationForwardTests.java index 60deff12bb88..43ba4272e2b8 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationForwardTests.java +++ b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationForwardTests.java @@ -38,8 +38,7 @@ class JspInstrumentationForwardTests extends AbstractHttpServerUsingTest { @RegisterExtension - public static final InstrumentationExtension testing = - HttpServerInstrumentationExtension.forAgent(); + static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent(); private static JspSpanAssertions spanAsserts; diff --git a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java index 7b9baa32c697..ed472287b78b 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java +++ b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java @@ -31,7 +31,7 @@ class JspSpanAssertions { this.port = port; } - SpanDataAssert assertServerSpan(SpanDataAssert span, JspSpan spanData) { + void assertServerSpan(SpanDataAssert span, JspSpan spanData) { if (spanData.getExceptionClass() != null) { span.hasStatus(StatusData.error()) .hasEventsSatisfyingExactly( @@ -58,7 +58,7 @@ SpanDataAssert assertServerSpan(SpanDataAssert span, JspSpan spanData) { val -> val.isInstanceOf(String.class)))); } - return span.hasName(spanData.getMethod() + " " + spanData.getRoute()) + span.hasName(spanData.getMethod() + " " + spanData.getRoute()) .hasNoParent() .hasKind(SpanKind.SERVER) .hasAttributesSatisfyingExactly( @@ -83,7 +83,7 @@ SpanDataAssert assertServerSpan(SpanDataAssert span, JspSpan spanData) { v -> assertThat(v).isEqualTo("500")))); } - SpanDataAssert assertCompileSpan(SpanDataAssert span, JspSpan spanData) { + void assertCompileSpan(SpanDataAssert span, JspSpan spanData) { if (spanData.getExceptionClass() != null) { span.hasStatus(StatusData.error()) .hasEventsSatisfyingExactly( @@ -102,7 +102,7 @@ SpanDataAssert assertCompileSpan(SpanDataAssert span, JspSpan spanData) { val -> val.isInstanceOf(String.class)))); } - return span.hasName("Compile " + spanData.getRoute()) + span.hasName("Compile " + spanData.getRoute()) .hasParent(spanData.getParent()) .hasAttributesSatisfyingExactly( equalTo(stringKey("jsp.classFQCN"), "org.apache.jsp." + spanData.getClassName()), From 6ee9f31fb72d411200e09f2ab5dea927606daede Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Mon, 10 Nov 2025 10:06:33 -0500 Subject: [PATCH 2/3] jsp tests --- docs/instrumentation-list.yaml | 33 ++++++++++++++ instrumentation-docs/instrumentations.sh | 2 + .../jsp-2.3/javaagent/build.gradle.kts | 40 +++++++++++------ .../jsp/JspInstrumentationBasicTests.java | 6 ++- .../jsp/JspSpanAssertions.java | 43 +++++++++++++------ instrumentation/jsp-2.3/metadata.yaml | 18 ++++++++ 6 files changed, 113 insertions(+), 29 deletions(-) create mode 100644 instrumentation/jsp-2.3/metadata.yaml diff --git a/docs/instrumentation-list.yaml b/docs/instrumentation-list.yaml index 3b0522e14b20..b77ae1ba9dcd 100644 --- a/docs/instrumentation-list.yaml +++ b/docs/instrumentation-list.yaml @@ -6859,12 +6859,45 @@ libraries: attributes: [] jsp: - name: jsp-2.3 + display_name: JSP (JavaServer Pages) + description: | + This instrumentation enables view spans for JSP page rendering and compilation (view spans are disabled by default). + library_link: https://jakarta.ee/specifications/pages/ + features: + - VIEW_SPANS source_path: instrumentation/jsp-2.3 scope: name: io.opentelemetry.jsp-2.3 target_versions: javaagent: - org.apache.tomcat:tomcat-jasper:[7.0.19,10) + configurations: + - name: otel.instrumentation.common.experimental.view-telemetry.enabled + description: Enables the creation of experimental view spans. + type: boolean + default: false + - name: otel.instrumentation.jsp.experimental-span-attributes + description: | + Enables experimental span attributes `jsp.forwardOrigin`, `jsp.requestURL`, `jsp.compiler`, and `jsp.classFQCN`. + type: boolean + default: false + telemetry: + - when: otel.instrumentation.common.experimental.view-telemetry.enabled=true + spans: + - span_kind: INTERNAL + attributes: [] + - when: otel.instrumentation.common.experimental.view-telemetry.enabled=true,otel.instrumentation.jsp.experimental-span-attributes=true + spans: + - span_kind: INTERNAL + attributes: + - name: jsp.classFQCN + type: STRING + - name: jsp.compiler + type: STRING + - name: jsp.forwardOrigin + type: STRING + - name: jsp.requestURL + type: STRING kafka: - name: kafka-clients-0.11 description: | diff --git a/instrumentation-docs/instrumentations.sh b/instrumentation-docs/instrumentations.sh index bb624ca1a48c..07d28e53df8f 100755 --- a/instrumentation-docs/instrumentations.sh +++ b/instrumentation-docs/instrumentations.sh @@ -146,6 +146,8 @@ readonly INSTRUMENTATIONS=( "jsf:jsf-mojarra-3.0:javaagent:test" "jsf:jsf-myfaces-1.2:javaagent:myfaces2Test" "jsf:jsf-myfaces-3.0:javaagent:test" + "jsp-2.3:javaagent:test" + "jsp-2.3:javaagent:testExperimental" "kafka:kafka-connect-2.6:testing:test" "nats:nats-2.17:javaagent:test" "nats:nats-2.17:javaagent:testExperimental" diff --git a/instrumentation/jsp-2.3/javaagent/build.gradle.kts b/instrumentation/jsp-2.3/javaagent/build.gradle.kts index 4e9539b44317..6eebdada3bcc 100644 --- a/instrumentation/jsp-2.3/javaagent/build.gradle.kts +++ b/instrumentation/jsp-2.3/javaagent/build.gradle.kts @@ -45,21 +45,33 @@ dependencies { latestDepTestLibrary("org.apache.tomcat.embed:tomcat-embed-logging-juli:9.+") // documented limitation } -tasks.withType().configureEach { - // skip jar scanning using environment variables: - // http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#JAR_Scanning - // having this set allows us to test with old versions of the tomcat api since - // JarScanFilter did not exist in the tomcat 7 api - jvmArgs("-Dorg.apache.catalina.startup.ContextConfig.jarsToSkip=*") - jvmArgs("-Dorg.apache.catalina.startup.TldConfig.jarsToSkip=*") +tasks { + withType().configureEach { + // skip jar scanning using environment variables: + // http://tomcat.apache.org/tomcat-7.0-doc/config/systemprops.html#JAR_Scanning + // having this set allows us to test with old versions of the tomcat api since + // JarScanFilter did not exist in the tomcat 7 api + jvmArgs("-Dorg.apache.catalina.startup.ContextConfig.jarsToSkip=*") + jvmArgs("-Dorg.apache.catalina.startup.TldConfig.jarsToSkip=*") - // required on jdk17 - jvmArgs("--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED") - jvmArgs("--add-opens=java.base/java.util=ALL-UNNAMED") - jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") + // required on jdk17 + jvmArgs("--add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED") + jvmArgs("--add-opens=java.base/java.util=ALL-UNNAMED") + jvmArgs("-XX:+IgnoreUnrecognizedVMOptions") + jvmArgs("-Dotel.instrumentation.common.experimental.view-telemetry.enabled=true") - // TODO run tests both with and without experimental span attributes - jvmArgs("-Dotel.instrumentation.jsp.experimental-span-attributes=true") + systemProperty("collectMetadata", findProperty("collectMetadata")?.toString() ?: "false") + } + + test { + systemProperty("metadataConfig", "otel.instrumentation.common.experimental.view-telemetry.enabled=true") + } - jvmArgs("-Dotel.instrumentation.common.experimental.view-telemetry.enabled=true") + val testExperimental by registering(Test::class) { + testClassesDirs = sourceSets.test.get().output.classesDirs + classpath = sourceSets.test.get().runtimeClasspath + + jvmArgs("-Dotel.instrumentation.jsp.experimental-span-attributes=true") + systemProperty("metadataConfig", "otel.instrumentation.common.experimental.view-telemetry.enabled=true,otel.instrumentation.jsp.experimental-span-attributes=true") + } } diff --git a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java index 9da7fabe6eaf..ccbda35e08f7 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java +++ b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspInstrumentationBasicTests.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.jsp; import static io.opentelemetry.api.common.AttributeKey.stringKey; +import static io.opentelemetry.javaagent.instrumentation.jsp.JspSpanAssertions.experimental; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @@ -427,10 +428,11 @@ void testCompileErrorShouldNotProduceRenderTracesAndSpans( .hasAttributesSatisfyingExactly( equalTo( stringKey("jsp.classFQCN"), - "org.apache.jsp." + jspClassNamePrefix + jspClassName), + experimental( + "org.apache.jsp." + jspClassNamePrefix + jspClassName)), equalTo( stringKey("jsp.compiler"), - "org.apache.jasper.compiler.JDTCompiler")))); + experimental("org.apache.jasper.compiler.JDTCompiler"))))); } private static Stream compileErrorsArgs() { diff --git a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java index ed472287b78b..004ef4241837 100644 --- a/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java +++ b/instrumentation/jsp-2.3/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jsp/JspSpanAssertions.java @@ -21,8 +21,12 @@ import io.opentelemetry.semconv.ServerAttributes; import io.opentelemetry.semconv.UrlAttributes; import io.opentelemetry.semconv.UserAgentAttributes; +import javax.annotation.Nullable; class JspSpanAssertions { + static final boolean isExperimentalEnabled = + Boolean.getBoolean("otel.instrumentation.jsp.experimental-span-attributes"); + private final String baseUrl; private final int port; @@ -31,6 +35,14 @@ class JspSpanAssertions { this.port = port; } + @Nullable + public static String experimental(String value) { + if (isExperimentalEnabled) { + return value; + } + return null; + } + void assertServerSpan(SpanDataAssert span, JspSpan spanData) { if (spanData.getExceptionClass() != null) { span.hasStatus(StatusData.error()) @@ -105,11 +117,14 @@ void assertCompileSpan(SpanDataAssert span, JspSpan spanData) { span.hasName("Compile " + spanData.getRoute()) .hasParent(spanData.getParent()) .hasAttributesSatisfyingExactly( - equalTo(stringKey("jsp.classFQCN"), "org.apache.jsp." + spanData.getClassName()), - equalTo(stringKey("jsp.compiler"), "org.apache.jasper.compiler.JDTCompiler")); + equalTo( + stringKey("jsp.classFQCN"), + experimental("org.apache.jsp." + spanData.getClassName())), + equalTo( + stringKey("jsp.compiler"), experimental("org.apache.jasper.compiler.JDTCompiler"))); } - SpanDataAssert assertRenderSpan(SpanDataAssert span, JspSpan spanData) { + void assertRenderSpan(SpanDataAssert span, JspSpan spanData) { String requestUrl = spanData.getRoute(); if (spanData.getRequestUrlOverride() != null) { requestUrl = spanData.getRequestUrlOverride(); @@ -141,15 +156,17 @@ SpanDataAssert assertRenderSpan(SpanDataAssert span, JspSpan spanData) { val -> val.isInstanceOf(String.class)))); } - return span.hasName("Render " + spanData.getRoute()) - .hasParent(spanData.getParent()) - .hasAttributesSatisfyingExactly( - equalTo(stringKey("jsp.requestURL"), baseUrl + requestUrl), - satisfies( - stringKey("jsp.forwardOrigin"), - val -> - val.satisfiesAnyOf( - v -> assertThat(spanData.getForwardOrigin()).isNull(), - v -> assertThat(v).isEqualTo(spanData.getForwardOrigin())))); + span.hasName("Render " + spanData.getRoute()).hasParent(spanData.getParent()); + + if (isExperimentalEnabled) { + span.hasAttributesSatisfyingExactly( + equalTo(stringKey("jsp.requestURL"), baseUrl + requestUrl), + satisfies( + stringKey("jsp.forwardOrigin"), + val -> + val.satisfiesAnyOf( + v -> assertThat(spanData.getForwardOrigin()).isNull(), + v -> assertThat(v).isEqualTo(spanData.getForwardOrigin())))); + } } } diff --git a/instrumentation/jsp-2.3/metadata.yaml b/instrumentation/jsp-2.3/metadata.yaml new file mode 100644 index 000000000000..37b8633565ac --- /dev/null +++ b/instrumentation/jsp-2.3/metadata.yaml @@ -0,0 +1,18 @@ +display_name: JSP (JavaServer Pages) +description: > + This instrumentation enables view spans for JSP page rendering and compilation (view spans are + disabled by default). +features: + - VIEW_SPANS +library_link: https://jakarta.ee/specifications/pages/ +configurations: + - name: otel.instrumentation.common.experimental.view-telemetry.enabled + description: Enables the creation of experimental view spans. + type: boolean + default: false + - name: otel.instrumentation.jsp.experimental-span-attributes + description: > + Enables experimental span attributes `jsp.forwardOrigin`, `jsp.requestURL`, `jsp.compiler`, + and `jsp.classFQCN`. + type: boolean + default: false \ No newline at end of file From 747c6ac0bb39ca740dd944c65424341d84bb0f3d Mon Sep 17 00:00:00 2001 From: Jay DeLuca Date: Mon, 17 Nov 2025 06:47:26 -0500 Subject: [PATCH 3/3] make JSP compile spans disabled by default --- .../jsp/JspCompilationContextInstrumentationSingletons.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/JspCompilationContextInstrumentationSingletons.java b/instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/JspCompilationContextInstrumentationSingletons.java index 28ce32f9ecca..ddb24d33023a 100644 --- a/instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/JspCompilationContextInstrumentationSingletons.java +++ b/instrumentation/jsp-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jsp/JspCompilationContextInstrumentationSingletons.java @@ -12,6 +12,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig; +import io.opentelemetry.javaagent.bootstrap.internal.ExperimentalConfig; import javax.annotation.Nullable; import org.apache.jasper.JspCompilationContext; import org.apache.jasper.compiler.Compiler; @@ -30,6 +31,7 @@ public class JspCompilationContextInstrumentationSingletons { "io.opentelemetry.jsp-2.3", JspCompilationContextInstrumentationSingletons::spanNameOnCompile) .addAttributesExtractor(new CompilationAttributesExtractor()) + .setEnabled(ExperimentalConfig.get().viewTelemetryEnabled()) .buildInstrumenter(SpanKindExtractor.alwaysInternal()); }