diff --git a/docs/instrumentation-list.yaml b/docs/instrumentation-list.yaml index 3d87266408e8..3dc6950f0b8d 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 display_name: Apache Kafka Client diff --git a/instrumentation-docs/instrumentations.sh b/instrumentation-docs/instrumentations.sh index 0ee9ec03592d..c2e1c2d0d2ea 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-clients:kafka-clients-2.6:library:test" "kafka:kafka-connect-2.6:testing:test" "nats:nats-2.17:javaagent:test" 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 f5642eaf4163..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; @@ -44,8 +45,7 @@ class JspInstrumentationBasicTests extends AbstractHttpServerUsingTest { @RegisterExtension - public static final InstrumentationExtension testing = - HttpServerInstrumentationExtension.forAgent(); + static final InstrumentationExtension testing = HttpServerInstrumentationExtension.forAgent(); private static JspSpanAssertions spanAsserts; @@ -428,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/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..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,7 +35,15 @@ class JspSpanAssertions { this.port = port; } - SpanDataAssert assertServerSpan(SpanDataAssert span, JspSpan spanData) { + @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()) .hasEventsSatisfyingExactly( @@ -58,7 +70,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 +95,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,14 +114,17 @@ 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()), - 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