Skip to content

Commit 14c363d

Browse files
authored
Merge pull request #5983 from getsentry/fix/data-collection-ktor-span-description
fix(ktor): [Data Collection 20] Exclude query parameters from span descriptions
2 parents 81a532a + c58f8d6 commit 14c363d

2 files changed

Lines changed: 20 additions & 9 deletions

File tree

‎sentry-ktor-client/src/main/java/io/sentry/ktorClient/SentryKtorClientPlugin.kt‎

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import io.sentry.util.Platform
2424
import io.sentry.util.PropagationTargetsUtils
2525
import io.sentry.util.SpanUtils
2626
import io.sentry.util.TracingUtils
27+
import io.sentry.util.UrlUtils
2728
import kotlinx.coroutines.withContext
2829

2930
/** Configuration for the Sentry Ktor client plugin. */
@@ -98,20 +99,20 @@ public val SentryKtorClientPlugin: ClientPlugin<SentryKtorClientPluginConfig> =
9899
val requestSpanKey = AttributeKey<ISpan>("SentryRequestSpan")
99100

100101
onRequest { request, _ ->
102+
val effectiveScopes = if (forceScopes) scopes else Sentry.getCurrentScopes()
101103
request.attributes.put(
102104
requestStartTimestampKey,
103-
(if (forceScopes) scopes else Sentry.getCurrentScopes()).options.dateProvider.now(),
105+
effectiveScopes.options.dateProvider.now(),
104106
)
105107

106108
val parentSpan: ISpan? =
107109
if (forceScopes) scopes.getSpan()
108-
else {
109-
val currentScopes = Sentry.getCurrentScopes()
110-
if (Platform.isAndroid()) currentScopes.transaction else currentScopes.span
111-
}
110+
else if (Platform.isAndroid()) effectiveScopes.transaction else effectiveScopes.span
112111

113112
val spanOp = "http.client"
114-
val spanDescription = "${request.method.value.toString()} ${request.url.buildString()}"
113+
val rawUrl = request.url.buildString()
114+
val urlDetails = UrlUtils.parse(rawUrl, effectiveScopes.options.dataCollectionResolver)
115+
val spanDescription = "${request.method.value.toString()} ${urlDetails.urlOrFallback}"
115116
val span: ISpan? = parentSpan?.startChild(spanOp, spanDescription)
116117
if (span != null) {
117118
span.spanContext.origin = TRACE_ORIGIN
@@ -120,13 +121,13 @@ public val SentryKtorClientPlugin: ClientPlugin<SentryKtorClientPluginConfig> =
120121

121122
if (
122123
!SpanUtils.isIgnored(
123-
(if (forceScopes) scopes else Sentry.getCurrentScopes()).options.getIgnoredSpanOrigins(),
124+
effectiveScopes.options.getIgnoredSpanOrigins(),
124125
TRACE_ORIGIN,
125126
)
126127
) {
127128
TracingUtils.traceIfAllowed(
128-
if (forceScopes) scopes else Sentry.getCurrentScopes(),
129-
request.url.buildString(),
129+
effectiveScopes,
130+
rawUrl,
130131
request.headers.getAll(BaggageHeader.BAGGAGE_HEADER),
131132
span,
132133
)

‎sentry-ktor-client/src/test/java/io/sentry/ktorClient/SentryKtorClientPluginTest.kt‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,16 @@ class SentryKtorClientPluginTest {
449449
assertTrue(httpClientSpan.isFinished)
450450
}
451451

452+
@Test
453+
fun `span description excludes query parameters and fragment`(): Unit = runBlocking {
454+
val sut = fixture.getSut()
455+
sut.get(fixture.server.url("/hello?token=secret&page=1#results").toString())
456+
457+
val httpClientSpan = fixture.sentryTracer.children.first()
458+
assertEquals("GET ${fixture.server.url("/hello")}", httpClientSpan.description)
459+
assertNull(httpClientSpan.data[SpanDataConvention.HTTP_QUERY_KEY])
460+
}
461+
452462
@Test
453463
fun `finishes span setting throwable and status when request throws`(): Unit = runBlocking {
454464
val sut = fixture.getSut(socketPolicy = SocketPolicy.DISCONNECT_DURING_REQUEST_BODY)

0 commit comments

Comments
 (0)