Skip to content

Commit 744a301

Browse files
committed
address review comment
1 parent 19ec2a2 commit 744a301

File tree

11 files changed

+359
-419
lines changed

11 files changed

+359
-419
lines changed

instrumentation/ktor/ktor-2-common/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/internal/KtorBuilderUtil.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import io.ktor.server.response.*
1212
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder
1313
import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpServerInstrumenterBuilder
1414
import io.opentelemetry.instrumentation.ktor.client.AbstractKtorClientTracingBuilder
15-
import io.opentelemetry.instrumentation.ktor.server.AbstractKtorServerTracing
15+
import io.opentelemetry.instrumentation.ktor.server.AbstractKtorServerTracingBuilder
1616

1717
/**
1818
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
@@ -21,6 +21,6 @@ import io.opentelemetry.instrumentation.ktor.server.AbstractKtorServerTracing
2121
object KtorBuilderUtil {
2222
lateinit var clientBuilderExtractor: (AbstractKtorClientTracingBuilder) -> DefaultHttpClientInstrumenterBuilder<HttpRequestData, HttpResponse>
2323
lateinit var serverBuilderExtractor: (
24-
AbstractKtorServerTracing.Configuration
24+
AbstractKtorServerTracingBuilder
2525
) -> DefaultHttpServerInstrumenterBuilder<ApplicationRequest, ApplicationResponse>
2626
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.ktor.internal
7+
8+
import io.ktor.server.application.*
9+
import io.ktor.server.request.*
10+
import io.ktor.server.response.*
11+
import io.opentelemetry.context.Context
12+
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter
13+
14+
class KtorServerTracer(
15+
private val instrumenter: Instrumenter<ApplicationRequest, ApplicationResponse>,
16+
) {
17+
fun start(call: ApplicationCall): Context? {
18+
val parentContext = Context.current()
19+
if (!instrumenter.shouldStart(parentContext, call.request)) {
20+
return null
21+
}
22+
23+
return instrumenter.start(parentContext, call.request)
24+
}
25+
26+
fun end(context: Context, call: ApplicationCall, error: Throwable?) {
27+
instrumenter.end(context, call.request, call.response, error)
28+
}
29+
}

instrumentation/ktor/ktor-2-common/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/internal/KtorServerTracingUtil.kt

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,79 @@
55

66
package io.opentelemetry.instrumentation.ktor.internal
77

8+
import io.ktor.server.application.*
89
import io.ktor.server.request.*
910
import io.ktor.server.response.*
11+
import io.ktor.util.*
12+
import io.ktor.util.pipeline.*
13+
import io.opentelemetry.context.Context
14+
import io.opentelemetry.extension.kotlin.asContextElement
1015
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter
1116
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor
1217
import io.opentelemetry.instrumentation.api.internal.InstrumenterUtil
13-
import io.opentelemetry.instrumentation.ktor.server.AbstractKtorServerTracing
18+
import io.opentelemetry.instrumentation.ktor.server.AbstractKtorServerTracingBuilder
1419
import io.opentelemetry.instrumentation.ktor.server.ApplicationRequestGetter
20+
import kotlinx.coroutines.withContext
1521

1622
/**
1723
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
1824
* any time.
1925
*/
2026
object KtorServerTracingUtil {
2127

22-
fun instrumenter(configuration: AbstractKtorServerTracing.Configuration): Instrumenter<ApplicationRequest, ApplicationResponse> {
28+
fun configureTracing(builder: AbstractKtorServerTracingBuilder, application: Application) {
29+
val contextKey = AttributeKey<Context>("OpenTelemetry")
30+
val errorKey = AttributeKey<Throwable>("OpenTelemetryException")
31+
32+
val instrumenter = instrumenter(builder)
33+
val tracer = KtorServerTracer(instrumenter)
34+
val startPhase = PipelinePhase("OpenTelemetry")
35+
36+
application.insertPhaseBefore(ApplicationCallPipeline.Monitoring, startPhase)
37+
application.intercept(startPhase) {
38+
val context = tracer.start(call)
39+
40+
if (context != null) {
41+
call.attributes.put(contextKey, context)
42+
withContext(context.asContextElement()) {
43+
try {
44+
proceed()
45+
} catch (err: Throwable) {
46+
// Stash error for reporting later since need ktor to finish setting up the response
47+
call.attributes.put(errorKey, err)
48+
throw err
49+
}
50+
}
51+
} else {
52+
proceed()
53+
}
54+
}
55+
56+
val postSendPhase = PipelinePhase("OpenTelemetryPostSend")
57+
application.sendPipeline.insertPhaseAfter(ApplicationSendPipeline.After, postSendPhase)
58+
application.sendPipeline.intercept(postSendPhase) {
59+
val context = call.attributes.getOrNull(contextKey)
60+
if (context != null) {
61+
var error: Throwable? = call.attributes.getOrNull(errorKey)
62+
try {
63+
proceed()
64+
} catch (t: Throwable) {
65+
error = t
66+
throw t
67+
} finally {
68+
tracer.end(context, call, error)
69+
}
70+
} else {
71+
proceed()
72+
}
73+
}
74+
}
75+
76+
private fun instrumenter(builder: AbstractKtorServerTracingBuilder): Instrumenter<ApplicationRequest, ApplicationResponse> {
2377
return InstrumenterUtil.buildUpstreamInstrumenter(
24-
configuration.serverBuilder.instrumenterBuilder(),
78+
builder.serverBuilder.instrumenterBuilder(),
2579
ApplicationRequestGetter,
26-
configuration.spanKindExtractor(SpanKindExtractor.alwaysServer())
80+
builder.spanKindExtractor(SpanKindExtractor.alwaysServer())
2781
)
2882
}
2983
}

instrumentation/ktor/ktor-2-common/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/server/AbstractKtorServerTracing.kt

Lines changed: 0 additions & 214 deletions
This file was deleted.

0 commit comments

Comments
 (0)