From a8a28ac34d7798c3739bc6409f6db57314567965 Mon Sep 17 00:00:00 2001 From: Mariia Skripchenko <61115099+marychatte@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:05:52 +0100 Subject: [PATCH 1/5] Add extensions for server v2 --- .../ktor/v2_0/ServerInstrumentation.java | 6 +- .../ktor/v2_0/server/KtorServerTracing.kt | 123 +++++++++++++++++- .../server/KtorServerSpanKindExtractorTest.kt | 13 +- .../ktor/v2_0/server/KtorTestUtil.kt | 4 +- 4 files changed, 130 insertions(+), 16 deletions(-) diff --git a/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/ServerInstrumentation.java b/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/ServerInstrumentation.java index c11a07fc4695..20ee790308d7 100644 --- a/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/ServerInstrumentation.java +++ b/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/ServerInstrumentation.java @@ -50,9 +50,9 @@ public static class SetupFunction public Unit invoke(KtorServerTracing.Configuration configuration) { OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); configuration.setOpenTelemetry(openTelemetry); - configuration.setCapturedRequestHeaders(CommonConfig.get().getServerRequestHeaders()); - configuration.setCapturedResponseHeaders(CommonConfig.get().getServerResponseHeaders()); - configuration.setKnownMethods(CommonConfig.get().getKnownHttpRequestMethods()); + configuration.capturedRequestHeaders(CommonConfig.get().getServerRequestHeaders()); + configuration.capturedResponseHeaders(CommonConfig.get().getServerResponseHeaders()); + configuration.knownMethods(CommonConfig.get().getKnownHttpRequestMethods()); return kotlin.Unit.INSTANCE; } diff --git a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt index 776c42c54b38..a9c8329a131c 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.ktor.v2_0.server +import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.request.* import io.ktor.server.response.* @@ -12,11 +13,14 @@ import io.ktor.server.routing.* import io.ktor.util.* import io.ktor.util.pipeline.* import io.opentelemetry.api.OpenTelemetry +import io.opentelemetry.api.common.AttributesBuilder +import io.opentelemetry.api.trace.SpanKind import io.opentelemetry.context.Context import io.opentelemetry.extension.kotlin.asContextElement import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor +import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusBuilder import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractor @@ -59,28 +63,143 @@ class KtorServerTracing private constructor( this.statusExtractor = extractor } + fun spanStatusExtractor(extract: SpanStatusData.() -> Unit) { + setStatusExtractor { + SpanStatusExtractor { spanStatusBuilder: SpanStatusBuilder, + request: ApplicationRequest, + response: ApplicationResponse?, + throwable: Throwable? -> + extract(SpanStatusData(spanStatusBuilder, request, response, throwable)) + } + } + } + + data class SpanStatusData( + val spanStatusBuilder: SpanStatusBuilder, + val request: ApplicationRequest, + val response: ApplicationResponse?, + val error: Throwable? + ) + fun setSpanKindExtractor(extractor: (SpanKindExtractor) -> SpanKindExtractor) { this.spanKindExtractor = extractor } + fun spanKindExtractor(extract: ApplicationRequest.() -> SpanKind) { + setSpanKindExtractor { + SpanKindExtractor { request: ApplicationRequest -> + extract(request) + } + } + } + fun addAttributeExtractor(extractor: AttributesExtractor) { additionalExtractors.add(extractor) } + fun attributeExtractor( + extractorBuilder: ExtractorBuilder.() -> Unit = {} + ) { + val builder = ExtractorBuilder().apply(extractorBuilder).build() + addAttributeExtractor( + object : AttributesExtractor { + override fun onStart(attributes: AttributesBuilder, parentContext: Context, request: ApplicationRequest) { + builder.onStart(OnStartData(attributes, parentContext, request)) + } + + override fun onEnd( + attributes: AttributesBuilder, + context: Context, + request: ApplicationRequest, + response: ApplicationResponse?, + error: Throwable? + ) { + builder.onEnd(OnEndData(attributes, context, request, response, error)) + } + } + ) + } + + class ExtractorBuilder { + private var onStart: OnStartData.() -> Unit = {} + private var onEnd: OnEndData.() -> Unit = {} + + fun onStart(block: OnStartData.() -> Unit) { + onStart = block + } + + fun onEnd(block: OnEndData.() -> Unit) { + onEnd = block + } + + internal fun build(): Extractor { + return Extractor(onStart, onEnd) + } + } + + internal class Extractor(val onStart: OnStartData.() -> Unit, val onEnd: OnEndData.() -> Unit) + + data class OnStartData( + val attributes: AttributesBuilder, + val parentContext: Context, + val request: ApplicationRequest + ) + + data class OnEndData( + val attributes: AttributesBuilder, + val parentContext: Context, + val request: ApplicationRequest, + val response: ApplicationResponse?, + val error: Throwable? + ) + fun setCapturedRequestHeaders(requestHeaders: List) { httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders) } + fun capturedRequestHeaders(headers: Iterable) { + setCapturedRequestHeaders(headers.toList()) + } + + fun capturedRequestHeaders(vararg headers: String) { + capturedRequestHeaders(headers.asIterable()) + } + fun setCapturedResponseHeaders(responseHeaders: List) { httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders) } + fun capturedResponseHeaders(headers: Iterable) { + setCapturedResponseHeaders(headers.toList()) + } + + fun capturedResponseHeaders(vararg headers: String) { + capturedResponseHeaders(headers.asIterable()) + } + fun setKnownMethods(knownMethods: Set) { httpAttributesExtractorBuilder.setKnownMethods(knownMethods) httpSpanNameExtractorBuilder.setKnownMethods(knownMethods) httpServerRouteBuilder.setKnownMethods(knownMethods) } + fun knownMethods(vararg methods: String) { + setKnownMethods(methods.toSet()) + } + + fun knownMethods(methods: Iterable) { + setKnownMethods(methods.toSet()) + } + + @JvmName("knownMethodsJvm") + fun knownMethods(methods: Iterable) { + knownMethods(methods.map { it.value }) + } + + fun knownMethods(vararg methods: HttpMethod) { + knownMethods(methods.map { it.value }) + } + internal fun isOpenTelemetryInitialized(): Boolean = this::openTelemetry.isInitialized } @@ -107,9 +226,7 @@ class KtorServerTracing private constructor( override fun install(pipeline: Application, configure: Configuration.() -> Unit): KtorServerTracing { val configuration = Configuration().apply(configure) - if (!configuration.isOpenTelemetryInitialized()) { - throw IllegalArgumentException("OpenTelemetry must be set") - } + require(configuration.isOpenTelemetryInitialized()) { "OpenTelemetry must be set" } val httpAttributesGetter = KtorHttpServerAttributesGetter.INSTANCE diff --git a/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerSpanKindExtractorTest.kt b/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerSpanKindExtractorTest.kt index 165c6afb7393..e4ab5d89391a 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerSpanKindExtractorTest.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerSpanKindExtractorTest.kt @@ -13,7 +13,6 @@ import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import io.opentelemetry.api.trace.SpanKind -import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpServerUsingTest import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension @@ -60,13 +59,11 @@ class KtorServerSpanKindExtractorTest : AbstractHttpServerUsingTest - if (req.uri.startsWith("/from-pubsub/")) { - SpanKind.CONSUMER - } else { - SpanKind.SERVER - } + spanKindExtractor { + if (uri.startsWith("/from-pubsub/")) { + SpanKind.CONSUMER + } else { + SpanKind.SERVER } } } diff --git a/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorTestUtil.kt b/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorTestUtil.kt index e6decdaf77d6..6a799635c1c5 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorTestUtil.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorTestUtil.kt @@ -14,8 +14,8 @@ class KtorTestUtil { fun installOpenTelemetry(application: Application, openTelemetry: OpenTelemetry) { application.install(KtorServerTracing) { setOpenTelemetry(openTelemetry) - setCapturedRequestHeaders(listOf(AbstractHttpServerTest.TEST_REQUEST_HEADER)) - setCapturedResponseHeaders(listOf(AbstractHttpServerTest.TEST_RESPONSE_HEADER)) + capturedRequestHeaders(AbstractHttpServerTest.TEST_REQUEST_HEADER) + capturedResponseHeaders(AbstractHttpServerTest.TEST_RESPONSE_HEADER) } } } From 1afd0e3677417f8584eb64e5121e040893a40f80 Mon Sep 17 00:00:00 2001 From: Mariia Skripchenko <61115099+marychatte@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:23:56 +0100 Subject: [PATCH 2/5] Add extensions for client v2 --- .../ktor/v2_0/HttpClientInstrumentation.java | 6 +- .../v2_0/client/KtorClientTracingBuilder.kt | 100 ++++++++++++++++++ .../ktor/v2_0/client/KtorHttpClientTest.kt | 4 +- 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/HttpClientInstrumentation.java b/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/HttpClientInstrumentation.java index 194ac50ff5ac..0a53968f9dc8 100644 --- a/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/HttpClientInstrumentation.java +++ b/instrumentation/ktor/ktor-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ktor/v2_0/HttpClientInstrumentation.java @@ -56,9 +56,9 @@ public static class SetupFunction implements Function1) { + setCapturedRequestHeaders(headers.toList()) + } + fun setCapturedResponseHeaders(vararg headers: String) = setCapturedResponseHeaders(headers.asList()) fun setCapturedResponseHeaders(headers: List) { httpAttributesExtractorBuilder.setCapturedResponseHeaders(headers) } + fun capturedResponseHeaders(vararg headers: String) { + capturedResponseHeaders(headers.asIterable()) + } + + fun capturedResponseHeaders(headers: Iterable) { + setCapturedResponseHeaders(headers.toList()) + } + fun setKnownMethods(knownMethods: Set) { httpAttributesExtractorBuilder.setKnownMethods(knownMethods) httpSpanNameExtractorBuilder.setKnownMethods(knownMethods) } + fun knownMethods(vararg methods: String) { + setKnownMethods(methods.toSet()) + } + + fun knownMethods(methods: Iterable) { + setKnownMethods(methods.toSet()) + } + + fun knownMethods(vararg methods: HttpMethod) { + knownMethods(methods.asIterable()) + } + + @JvmName("knownMethodsJvm") + fun knownMethods(methods: Iterable) { + setKnownMethods(methods.map { it.value }.toSet()) + } + fun addAttributesExtractors(vararg extractors: AttributesExtractor) = addAttributesExtractors(extractors.asList()) fun addAttributesExtractors(extractors: Iterable>) { additionalExtractors += extractors } + fun attributeExtractor( + extractorBuilder: ExtractorBuilder.() -> Unit = {} + ) { + val builder = ExtractorBuilder().apply(extractorBuilder).build() + addAttributesExtractors( + object : AttributesExtractor { + override fun onStart( + attributes: AttributesBuilder, + parentContext: Context, + request: HttpRequestData + ) { + builder.onStart(OnStartData(attributes, parentContext, request)) + } + + override fun onEnd( + attributes: AttributesBuilder, + context: Context, + request: HttpRequestData, + response: HttpResponse?, + error: Throwable? + ) { + builder.onEnd(OnEndData(attributes, context, request, response, error)) + } + } + ) + } + + class ExtractorBuilder { + private var onStart: OnStartData.() -> Unit = {} + private var onEnd: OnEndData.() -> Unit = {} + + fun onStart(block: OnStartData.() -> Unit) { + onStart = block + } + + fun onEnd(block: OnEndData.() -> Unit) { + onEnd = block + } + + internal fun build(): Extractor { + return Extractor(onStart, onEnd) + } + } + + internal class Extractor(val onStart: OnStartData.() -> Unit, val onEnd: OnEndData.() -> Unit) + + data class OnStartData( + val attributes: AttributesBuilder, + val parentContext: Context, + val request: HttpRequestData + ) + + data class OnEndData( + val attributes: AttributesBuilder, + val parentContext: Context, + val request: HttpRequestData, + val response: HttpResponse?, + val error: Throwable? + ) + /** * Configures the instrumentation to emit experimental HTTP client metrics. * @@ -63,6 +159,10 @@ class KtorClientTracingBuilder { this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics } + fun emitExperimentalHttpClientMetrics() { + setEmitExperimentalHttpClientMetrics(true) + } + internal fun build(): KtorClientTracing { val initializedOpenTelemetry = openTelemetry ?: throw IllegalArgumentException("OpenTelemetry must be set") diff --git a/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorHttpClientTest.kt b/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorHttpClientTest.kt index 0d9fa7971774..ada0183d30a1 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorHttpClientTest.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorHttpClientTest.kt @@ -20,8 +20,8 @@ class KtorHttpClientTest : AbstractKtorHttpClientTest() { override fun HttpClientConfig<*>.installTracing() { install(KtorClientTracing) { setOpenTelemetry(TESTING.openTelemetry) - setCapturedRequestHeaders(listOf(TEST_REQUEST_HEADER)) - setCapturedResponseHeaders(listOf(TEST_RESPONSE_HEADER)) + capturedRequestHeaders(TEST_REQUEST_HEADER) + capturedResponseHeaders(TEST_RESPONSE_HEADER) } } } From a2c7ad845c6eda15b067bac44b3e2be1e18c4e9e Mon Sep 17 00:00:00 2001 From: Mariia Skripchenko <61115099+marychatte@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:32:20 +0100 Subject: [PATCH 3/5] fix spotlessKotlinCheck --- .../v2_0/client/KtorClientTracingBuilder.kt | 18 +++--------------- .../ktor/v2_0/server/KtorServerTracing.kt | 12 ++---------- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt index 6792dd186fd1..ede6c52c0726 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt @@ -90,27 +90,15 @@ class KtorClientTracingBuilder { additionalExtractors += extractors } - fun attributeExtractor( - extractorBuilder: ExtractorBuilder.() -> Unit = {} - ) { + fun attributeExtractor(extractorBuilder: ExtractorBuilder.() -> Unit = {}) { val builder = ExtractorBuilder().apply(extractorBuilder).build() addAttributesExtractors( object : AttributesExtractor { - override fun onStart( - attributes: AttributesBuilder, - parentContext: Context, - request: HttpRequestData - ) { + override fun onStart(attributes: AttributesBuilder, parentContext: Context, request: HttpRequestData) { builder.onStart(OnStartData(attributes, parentContext, request)) } - override fun onEnd( - attributes: AttributesBuilder, - context: Context, - request: HttpRequestData, - response: HttpResponse?, - error: Throwable? - ) { + override fun onEnd(attributes: AttributesBuilder, context: Context, request: HttpRequestData, response: HttpResponse?, error: Throwable?) { builder.onEnd(OnEndData(attributes, context, request, response, error)) } } diff --git a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt index a9c8329a131c..ca61f6178cc6 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt @@ -97,9 +97,7 @@ class KtorServerTracing private constructor( additionalExtractors.add(extractor) } - fun attributeExtractor( - extractorBuilder: ExtractorBuilder.() -> Unit = {} - ) { + fun attributeExtractor(extractorBuilder: ExtractorBuilder.() -> Unit = {}) { val builder = ExtractorBuilder().apply(extractorBuilder).build() addAttributeExtractor( object : AttributesExtractor { @@ -107,13 +105,7 @@ class KtorServerTracing private constructor( builder.onStart(OnStartData(attributes, parentContext, request)) } - override fun onEnd( - attributes: AttributesBuilder, - context: Context, - request: ApplicationRequest, - response: ApplicationResponse?, - error: Throwable? - ) { + override fun onEnd(attributes: AttributesBuilder, context: Context, request: ApplicationRequest, response: ApplicationResponse?, error: Throwable?) { builder.onEnd(OnEndData(attributes, context, request, response, error)) } } From 15042d780e0a36d6652d76594342616fa3a74786 Mon Sep 17 00:00:00 2001 From: Mariia Skripchenko <61115099+marychatte@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:25:35 +0200 Subject: [PATCH 4/5] Fix extractors: add previous extractor as a parameter --- .../ktor/v2_0/server/KtorServerTracing.kt | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt index ca61f6178cc6..f1ffbf9fa071 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt @@ -60,16 +60,18 @@ class KtorServerTracing private constructor( fun setStatusExtractor( extractor: (SpanStatusExtractor) -> SpanStatusExtractor ) { - this.statusExtractor = extractor + spanStatusExtractor { prevStatusExtractor -> + extractor(prevStatusExtractor).extract(spanStatusBuilder, request, response, error) + } } - fun spanStatusExtractor(extract: SpanStatusData.() -> Unit) { - setStatusExtractor { + fun spanStatusExtractor(extract: SpanStatusData.(SpanStatusExtractor) -> Unit) { + statusExtractor = { prevExtractor -> SpanStatusExtractor { spanStatusBuilder: SpanStatusBuilder, request: ApplicationRequest, response: ApplicationResponse?, throwable: Throwable? -> - extract(SpanStatusData(spanStatusBuilder, request, response, throwable)) + extract(SpanStatusData(spanStatusBuilder, request, response, throwable), prevExtractor) } } } @@ -82,24 +84,33 @@ class KtorServerTracing private constructor( ) fun setSpanKindExtractor(extractor: (SpanKindExtractor) -> SpanKindExtractor) { - this.spanKindExtractor = extractor + spanKindExtractor { prevSpanKindExtractor -> + extractor(prevSpanKindExtractor).extract(this) + } } - fun spanKindExtractor(extract: ApplicationRequest.() -> SpanKind) { - setSpanKindExtractor { + fun spanKindExtractor(extract: ApplicationRequest.(SpanKindExtractor) -> SpanKind) { + spanKindExtractor = { prevExtractor -> SpanKindExtractor { request: ApplicationRequest -> - extract(request) + extract(request, prevExtractor) } } } fun addAttributeExtractor(extractor: AttributesExtractor) { - additionalExtractors.add(extractor) + attributeExtractor { + onStart { + extractor.onStart(attributes, parentContext, request) + } + onEnd { + extractor.onEnd(attributes, parentContext, request, response, error) + } + } } fun attributeExtractor(extractorBuilder: ExtractorBuilder.() -> Unit = {}) { val builder = ExtractorBuilder().apply(extractorBuilder).build() - addAttributeExtractor( + additionalExtractors.add( object : AttributesExtractor { override fun onStart(attributes: AttributesBuilder, parentContext: Context, request: ApplicationRequest) { builder.onStart(OnStartData(attributes, parentContext, request)) From 434354567148c785a3e161927105743d2f197563 Mon Sep 17 00:00:00 2001 From: Mariia Skripchenko <61115099+marychatte@users.noreply.github.com> Date: Thu, 25 Apr 2024 20:57:14 +0200 Subject: [PATCH 5/5] Add deprecations --- .../v2_0/client/KtorClientTracingBuilder.kt | 88 +++++++++++-------- .../ktor/v2_0/server/KtorServerTracing.kt | 63 ++++++------- 2 files changed, 84 insertions(+), 67 deletions(-) diff --git a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt index ede6c52c0726..654bacda482e 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/client/KtorClientTracingBuilder.kt @@ -34,65 +34,78 @@ class KtorClientTracingBuilder { this.openTelemetry = openTelemetry } - fun setCapturedRequestHeaders(vararg headers: String) = setCapturedRequestHeaders(headers.asList()) + @Deprecated( + "Please use method `capturedRequestHeaders`", + ReplaceWith("capturedRequestHeaders(headers.asIterable())") + ) + fun setCapturedRequestHeaders(vararg headers: String) = capturedRequestHeaders(headers.asIterable()) - fun setCapturedRequestHeaders(headers: List) { - httpAttributesExtractorBuilder.setCapturedRequestHeaders(headers) - } + @Deprecated( + "Please use method `capturedRequestHeaders`", + ReplaceWith("capturedRequestHeaders(headers)") + ) + fun setCapturedRequestHeaders(headers: List) = capturedRequestHeaders(headers) - fun capturedRequestHeaders(vararg headers: String) { - capturedRequestHeaders(headers.asIterable()) - } + fun capturedRequestHeaders(vararg headers: String) = capturedRequestHeaders(headers.asIterable()) fun capturedRequestHeaders(headers: Iterable) { - setCapturedRequestHeaders(headers.toList()) + httpAttributesExtractorBuilder.setCapturedRequestHeaders(headers.toList()) } - fun setCapturedResponseHeaders(vararg headers: String) = setCapturedResponseHeaders(headers.asList()) + @Deprecated( + "Please use method `capturedResponseHeaders`", + ReplaceWith("capturedResponseHeaders(headers.asIterable())") + ) + fun setCapturedResponseHeaders(vararg headers: String) = capturedResponseHeaders(headers.asIterable()) - fun setCapturedResponseHeaders(headers: List) { - httpAttributesExtractorBuilder.setCapturedResponseHeaders(headers) - } + @Deprecated( + "Please use method `capturedResponseHeaders`", + ReplaceWith("capturedResponseHeaders(headers)") + ) + fun setCapturedResponseHeaders(headers: List) = capturedResponseHeaders(headers) - fun capturedResponseHeaders(vararg headers: String) { - capturedResponseHeaders(headers.asIterable()) - } + fun capturedResponseHeaders(vararg headers: String) = capturedResponseHeaders(headers.asIterable()) fun capturedResponseHeaders(headers: Iterable) { - setCapturedResponseHeaders(headers.toList()) + httpAttributesExtractorBuilder.setCapturedResponseHeaders(headers.toList()) } - fun setKnownMethods(knownMethods: Set) { - httpAttributesExtractorBuilder.setKnownMethods(knownMethods) - httpSpanNameExtractorBuilder.setKnownMethods(knownMethods) - } - - fun knownMethods(vararg methods: String) { - setKnownMethods(methods.toSet()) - } + @Deprecated( + "Please use method `knownMethods`", + ReplaceWith("knownMethods(knownMethods)") + ) + fun setKnownMethods(knownMethods: Set) = knownMethods(knownMethods) - fun knownMethods(methods: Iterable) { - setKnownMethods(methods.toSet()) - } + fun knownMethods(vararg methods: String) = knownMethods(methods.asIterable()) - fun knownMethods(vararg methods: HttpMethod) { - knownMethods(methods.asIterable()) - } + fun knownMethods(vararg methods: HttpMethod) = knownMethods(methods.asIterable()) @JvmName("knownMethodsJvm") - fun knownMethods(methods: Iterable) { - setKnownMethods(methods.map { it.value }.toSet()) + fun knownMethods(methods: Iterable) = knownMethods(methods.map { it.value }) + + fun knownMethods(methods: Iterable) { + methods.toSet().apply { + httpAttributesExtractorBuilder.setKnownMethods(this) + httpSpanNameExtractorBuilder.setKnownMethods(this) + } } + @Deprecated("Please use method `attributeExtractor`") fun addAttributesExtractors(vararg extractors: AttributesExtractor) = addAttributesExtractors(extractors.asList()) + @Deprecated("Please use method `attributeExtractor`") fun addAttributesExtractors(extractors: Iterable>) { - additionalExtractors += extractors + extractors.forEach { + attributeExtractor { + onStart { it.onStart(attributes, parentContext, request) } + onEnd { it.onEnd(attributes, parentContext, request, response, error) } + } + } } fun attributeExtractor(extractorBuilder: ExtractorBuilder.() -> Unit = {}) { val builder = ExtractorBuilder().apply(extractorBuilder).build() - addAttributesExtractors( + additionalExtractors.add( object : AttributesExtractor { override fun onStart(attributes: AttributesBuilder, parentContext: Context, request: HttpRequestData) { builder.onStart(OnStartData(attributes, parentContext, request)) @@ -143,12 +156,15 @@ class KtorClientTracingBuilder { * * @param emitExperimentalHttpClientMetrics `true` if the experimental HTTP client metrics are to be emitted. */ + @Deprecated("Please use method `emitExperimentalHttpClientMetrics`") fun setEmitExperimentalHttpClientMetrics(emitExperimentalHttpClientMetrics: Boolean) { - this.emitExperimentalHttpClientMetrics = emitExperimentalHttpClientMetrics + if (emitExperimentalHttpClientMetrics) { + emitExperimentalHttpClientMetrics() + } } fun emitExperimentalHttpClientMetrics() { - setEmitExperimentalHttpClientMetrics(true) + emitExperimentalHttpClientMetrics = true } internal fun build(): KtorClientTracing { diff --git a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt index f1ffbf9fa071..2e4c203eb3ed 100644 --- a/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt +++ b/instrumentation/ktor/ktor-2.0/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/server/KtorServerTracing.kt @@ -57,6 +57,7 @@ class KtorServerTracing private constructor( this.openTelemetry = openTelemetry } + @Deprecated("Please use method `spanStatusExtractor`") fun setStatusExtractor( extractor: (SpanStatusExtractor) -> SpanStatusExtractor ) { @@ -83,6 +84,7 @@ class KtorServerTracing private constructor( val error: Throwable? ) + @Deprecated("Please use method `spanKindExtractor`") fun setSpanKindExtractor(extractor: (SpanKindExtractor) -> SpanKindExtractor) { spanKindExtractor { prevSpanKindExtractor -> extractor(prevSpanKindExtractor).extract(this) @@ -97,6 +99,7 @@ class KtorServerTracing private constructor( } } + @Deprecated("Please use method `attributeExtractor`") fun addAttributeExtractor(extractor: AttributesExtractor) { attributeExtractor { onStart { @@ -156,51 +159,49 @@ class KtorServerTracing private constructor( val error: Throwable? ) - fun setCapturedRequestHeaders(requestHeaders: List) { - httpAttributesExtractorBuilder.setCapturedRequestHeaders(requestHeaders) - } + @Deprecated( + "Please use method `capturedRequestHeaders`", + ReplaceWith("capturedRequestHeaders(headers)") + ) + fun setCapturedRequestHeaders(headers: List) = capturedRequestHeaders(headers) + + fun capturedRequestHeaders(vararg headers: String) = capturedRequestHeaders(headers.asIterable()) fun capturedRequestHeaders(headers: Iterable) { - setCapturedRequestHeaders(headers.toList()) + httpAttributesExtractorBuilder.setCapturedRequestHeaders(headers.toList()) } - fun capturedRequestHeaders(vararg headers: String) { - capturedRequestHeaders(headers.asIterable()) - } + @Deprecated( + "Please use method `capturedResponseHeaders`", + ReplaceWith("capturedResponseHeaders(headers)") + ) + fun setCapturedResponseHeaders(headers: List) = capturedResponseHeaders(headers) - fun setCapturedResponseHeaders(responseHeaders: List) { - httpAttributesExtractorBuilder.setCapturedResponseHeaders(responseHeaders) - } + fun capturedResponseHeaders(vararg headers: String) = capturedResponseHeaders(headers.asIterable()) fun capturedResponseHeaders(headers: Iterable) { - setCapturedResponseHeaders(headers.toList()) - } - - fun capturedResponseHeaders(vararg headers: String) { - capturedResponseHeaders(headers.asIterable()) + httpAttributesExtractorBuilder.setCapturedResponseHeaders(headers.toList()) } - fun setKnownMethods(knownMethods: Set) { - httpAttributesExtractorBuilder.setKnownMethods(knownMethods) - httpSpanNameExtractorBuilder.setKnownMethods(knownMethods) - httpServerRouteBuilder.setKnownMethods(knownMethods) - } + @Deprecated( + "Please use method `knownMethods`", + ReplaceWith("knownMethods(knownMethods)") + ) + fun setKnownMethods(knownMethods: Set) = knownMethods(knownMethods) - fun knownMethods(vararg methods: String) { - setKnownMethods(methods.toSet()) - } + fun knownMethods(vararg methods: String) = knownMethods(methods.asIterable()) - fun knownMethods(methods: Iterable) { - setKnownMethods(methods.toSet()) - } + fun knownMethods(vararg methods: HttpMethod) = knownMethods(methods.asIterable()) @JvmName("knownMethodsJvm") - fun knownMethods(methods: Iterable) { - knownMethods(methods.map { it.value }) - } + fun knownMethods(methods: Iterable) = knownMethods(methods.map { it.value }) - fun knownMethods(vararg methods: HttpMethod) { - knownMethods(methods.map { it.value }) + fun knownMethods(methods: Iterable) { + methods.toSet().apply { + httpAttributesExtractorBuilder.setKnownMethods(this) + httpSpanNameExtractorBuilder.setKnownMethods(this) + httpServerRouteBuilder.setKnownMethods(this) + } } internal fun isOpenTelemetryInitialized(): Boolean = this::openTelemetry.isInitialized