@@ -14,73 +14,73 @@ import io.ktor.util.pipeline.*
1414import io.opentelemetry.api.OpenTelemetry
1515import io.opentelemetry.context.Context
1616import io.opentelemetry.extension.kotlin.asContextElement
17+ import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpServerTelemetryBuilder
1718import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor
1819import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter
1920import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor
21+ import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusBuilder
2022import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor
2123import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil
22- import io.opentelemetry.instrumentation.api.semconv.http.HttpServerAttributesExtractor
23- import io.opentelemetry.instrumentation.api.semconv.http.HttpServerMetrics
2424import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRoute
2525import io.opentelemetry.instrumentation.api.semconv.http.HttpServerRouteSource
26- import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanNameExtractor
27- import io.opentelemetry.instrumentation.api.semconv.http.HttpSpanStatusExtractor
2826import kotlinx.coroutines.withContext
27+ import java.util.Optional
2928
3029class KtorServerTracing private constructor(
3130 private val instrumenter : Instrumenter <ApplicationRequest , ApplicationResponse >,
3231) {
3332
3433 class Configuration {
35- internal lateinit var openTelemetry: OpenTelemetry
36-
37- internal val additionalExtractors = mutableListOf<AttributesExtractor <in ApplicationRequest , in ApplicationResponse >>()
38-
39- internal val httpAttributesExtractorBuilder = HttpServerAttributesExtractor .builder(KtorHttpServerAttributesGetter .INSTANCE )
40-
41- internal val httpSpanNameExtractorBuilder = HttpSpanNameExtractor .builder(KtorHttpServerAttributesGetter .INSTANCE )
42-
43- internal val httpServerRouteBuilder = HttpServerRoute .builder(KtorHttpServerAttributesGetter .INSTANCE )
44-
45- internal var statusExtractor:
46- (SpanStatusExtractor <ApplicationRequest , ApplicationResponse >) -> SpanStatusExtractor <in ApplicationRequest , in ApplicationResponse > = { a -> a }
34+ internal lateinit var serverBuilder: DefaultHttpServerTelemetryBuilder <ApplicationRequest , ApplicationResponse >
4735
4836 internal var spanKindExtractor:
4937 (SpanKindExtractor <ApplicationRequest >) -> SpanKindExtractor <ApplicationRequest > = { a -> a }
5038
5139 fun setOpenTelemetry (openTelemetry : OpenTelemetry ) {
52- this .openTelemetry = openTelemetry
40+ this .serverBuilder = DefaultHttpServerTelemetryBuilder (
41+ INSTRUMENTATION_NAME ,
42+ openTelemetry,
43+ KtorHttpServerAttributesGetter .INSTANCE ,
44+ Optional .empty()
45+ )
5346 }
5447
5548 fun setStatusExtractor (
5649 extractor : (SpanStatusExtractor <ApplicationRequest , ApplicationResponse >) -> SpanStatusExtractor <in ApplicationRequest , in ApplicationResponse >
5750 ) {
58- this .statusExtractor = extractor
51+ serverBuilder.setStatusExtractor{ prevExtractor ->
52+ SpanStatusExtractor { spanStatusBuilder: SpanStatusBuilder ,
53+ request: ApplicationRequest ,
54+ response: ApplicationResponse ? ,
55+ throwable: Throwable ? ->
56+ @Suppress(" UNCHECKED_CAST" )
57+ extractor(prevExtractor as SpanStatusExtractor <ApplicationRequest , ApplicationResponse >)
58+ .extract(spanStatusBuilder, request, response, throwable)
59+ }
60+ }
5961 }
6062
6163 fun setSpanKindExtractor (extractor : (SpanKindExtractor <ApplicationRequest >) -> SpanKindExtractor <ApplicationRequest >) {
6264 this .spanKindExtractor = extractor
6365 }
6466
6567 fun addAttributeExtractor (extractor : AttributesExtractor <in ApplicationRequest , in ApplicationResponse >) {
66- additionalExtractors.add (extractor)
68+ serverBuilder.addAttributesExtractor (extractor)
6769 }
6870
6971 fun setCapturedRequestHeaders (requestHeaders : List <String >) {
70- httpAttributesExtractorBuilder .setCapturedRequestHeaders(requestHeaders)
72+ serverBuilder .setCapturedRequestHeaders(requestHeaders)
7173 }
7274
7375 fun setCapturedResponseHeaders (responseHeaders : List <String >) {
74- httpAttributesExtractorBuilder .setCapturedResponseHeaders(responseHeaders)
76+ serverBuilder .setCapturedResponseHeaders(responseHeaders)
7577 }
7678
7779 fun setKnownMethods (knownMethods : Set <String >) {
78- httpAttributesExtractorBuilder.setKnownMethods(knownMethods)
79- httpSpanNameExtractorBuilder.setKnownMethods(knownMethods)
80- httpServerRouteBuilder.setKnownMethods(knownMethods)
80+ serverBuilder.setKnownMethods(knownMethods)
8181 }
8282
83- internal fun isOpenTelemetryInitialized (): Boolean = this ::openTelemetry .isInitialized
83+ internal fun isOpenTelemetryInitialized (): Boolean = this ::serverBuilder .isInitialized
8484 }
8585
8686 private fun start (call : ApplicationCall ): Context ? {
@@ -111,25 +111,8 @@ class KtorServerTracing private constructor(
111111 throw IllegalArgumentException (" OpenTelemetry must be set" )
112112 }
113113
114- val httpAttributesGetter = KtorHttpServerAttributesGetter .INSTANCE
115-
116- val instrumenterBuilder = Instrumenter .builder<ApplicationRequest , ApplicationResponse >(
117- configuration.openTelemetry,
118- INSTRUMENTATION_NAME ,
119- configuration.httpSpanNameExtractorBuilder.build()
120- )
121-
122- configuration.additionalExtractors.forEach { instrumenterBuilder.addAttributesExtractor(it) }
123-
124- with (instrumenterBuilder) {
125- setSpanStatusExtractor(configuration.statusExtractor(HttpSpanStatusExtractor .create(httpAttributesGetter)))
126- addAttributesExtractor(configuration.httpAttributesExtractorBuilder.build())
127- addOperationMetrics(HttpServerMetrics .get())
128- addContextCustomizer(configuration.httpServerRouteBuilder.build())
129- }
130-
131114 val instrumenter = InstrumenterUtil .buildUpstreamInstrumenter(
132- instrumenterBuilder,
115+ configuration.serverBuilder. instrumenterBuilder {} ,
133116 ApplicationRequestGetter ,
134117 configuration.spanKindExtractor(SpanKindExtractor .alwaysServer())
135118 )
0 commit comments