Skip to content

Commit 9903a0e

Browse files
authored
Insert OpenTelemetry phase before Setup (#13239)
1 parent 85a52ca commit 9903a0e

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

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

+14-8
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,32 @@ object KtorServerTelemetryUtil {
3333
val tracer = KtorServerTracer(instrumenter)
3434
val startPhase = PipelinePhase("OpenTelemetry")
3535

36-
application.insertPhaseBefore(ApplicationCallPipeline.Monitoring, startPhase)
36+
application.insertPhaseBefore(ApplicationCallPipeline.Setup, startPhase)
3737
application.intercept(startPhase) {
3838
val context = tracer.start(call)
3939

4040
if (context != null) {
4141
call.attributes.put(contextKey, context)
4242
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-
}
43+
proceed()
5044
}
5145
} else {
5246
proceed()
5347
}
5448
}
5549

50+
val errorPhase = PipelinePhase("OpenTelemetryError")
51+
application.insertPhaseBefore(ApplicationCallPipeline.Monitoring, errorPhase)
52+
application.intercept(errorPhase) {
53+
try {
54+
proceed()
55+
} catch (err: Throwable) {
56+
// Stash error for reporting later since need ktor to finish setting up the response
57+
call.attributes.put(errorKey, err)
58+
throw err
59+
}
60+
}
61+
5662
val postSendPhase = PipelinePhase("OpenTelemetryPostSend")
5763
application.sendPipeline.insertPhaseAfter(ApplicationSendPipeline.After, postSendPhase)
5864
application.sendPipeline.intercept(postSendPhase) {

instrumentation/ktor/ktor-3.0/library/README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ implementation("io.opentelemetry.instrumentation:opentelemetry-ktor-3.0:OPENTELE
3232

3333
## Initializing server instrumentation
3434

35-
Initialize instrumentation by installing the `KtorServerTelemetry` feature.
35+
Initialize instrumentation by installing the `KtorServerTelemetry` feature. Make sure that no other
36+
logging plugin is installed before this.
3637
You must set the `OpenTelemetry` to use with the feature.
3738

3839
```kotlin

instrumentation/ktor/ktor-3.0/library/src/test/kotlin/io/opentelemetry/instrumentation/ktor/v3_0/KtorHttpServerTest.kt

+10
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@
55

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

8+
import io.ktor.http.HttpStatusCode
89
import io.ktor.server.application.*
10+
import io.ktor.server.application.hooks.CallFailed
11+
import io.ktor.server.response.respondText
912
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension
1013
import io.opentelemetry.instrumentation.testing.junit.http.HttpServerInstrumentationExtension
14+
import io.opentelemetry.instrumentation.testing.junit.http.ServerEndpoint
1115
import org.junit.jupiter.api.extension.RegisterExtension
1216

1317
class KtorHttpServerTest : AbstractKtorHttpServerTest() {
@@ -27,6 +31,12 @@ class KtorHttpServerTest : AbstractKtorHttpServerTest() {
2731
capturedRequestHeaders(TEST_REQUEST_HEADER)
2832
capturedResponseHeaders(TEST_RESPONSE_HEADER)
2933
}
34+
35+
install(createRouteScopedPlugin("Failure handler, that can mask exceptions if exception handling is in the wrong phase", ServerEndpoint.EXCEPTION.path, {}) {
36+
on(CallFailed) { call, cause ->
37+
call.respondText("failure: ${cause.message}", status = HttpStatusCode.InternalServerError)
38+
}
39+
})
3040
}
3141
}
3242
}

0 commit comments

Comments
 (0)