Skip to content

Commit a88509c

Browse files
adinauerbruno-garciaromtsngetsentry-bot
authored
Replace tracestate header with baggage (#2078)
* Replace tracestate header with baggage * Update changelog with PR number * Re-add experimental flag * Add more tests to document current behaviour * Mark places where header could be added * Remove unused code * Add tests to document which characters are encoded for baggage key and value * Mark places where header could be added * Change limit from per value to total baggage string length of 8192; also limit list members to 64 for baggage * Add baggage header to apollo, feign and web requests * Add final; use constants in tests * Add log message for exceeding list member limit * Update sentry/src/main/java/io/sentry/SentryOptions.java Co-authored-by: Roman Zavarnitsyn <[email protected]> * Update sentry/src/main/java/io/sentry/SentryOptions.java Co-authored-by: Roman Zavarnitsyn <[email protected]> * Update sentry/src/main/java/io/sentry/Baggage.java Co-authored-by: Roman Zavarnitsyn <[email protected]> * Update sentry/src/main/java/io/sentry/Baggage.java Co-authored-by: Roman Zavarnitsyn <[email protected]> * Update sentry/src/main/java/io/sentry/Baggage.java Co-authored-by: Roman Zavarnitsyn <[email protected]> * Update sentry/src/main/java/io/sentry/SentryOptions.java Co-authored-by: Roman Zavarnitsyn <[email protected]> * Update sentry/src/main/java/io/sentry/SentryOptions.java Co-authored-by: Roman Zavarnitsyn <[email protected]> * More Code Review changes * Format code * Remove files that were unintentionally added Co-authored-by: Bruno Garcia <[email protected]> Co-authored-by: Roman Zavarnitsyn <[email protected]> Co-authored-by: Sentry Github Bot <[email protected]>
1 parent 580aa75 commit a88509c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1250
-359
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Features
6+
7+
- Replace `tracestate` header with `baggage` header ([#2078](https://github.com/getsentry/sentry-java/pull/2078))
8+
39
## 6.1.0
410

511
### Features

buildSrc/src/main/java/Config.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ object Config {
134134
val mockWebserver3 = "com.squareup.okhttp3:mockwebserver:3.14.9"
135135
val jsonUnit = "net.javacrumbs.json-unit:json-unit:2.32.0"
136136
val hsqldb = "org.hsqldb:hsqldb:2.6.1"
137+
val javaFaker = "com.github.javafaker:javafaker:1.0.2"
137138
}
138139

139140
object QualityPlugins {

sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import io.sentry.SentryLevel
2020
import io.sentry.SentryOptions
2121
import io.sentry.SentryTracer
2222
import io.sentry.SpanStatus
23-
import io.sentry.TraceState
23+
import io.sentry.TraceContext
2424
import io.sentry.TransactionContext
2525
import io.sentry.TransactionFinishedCallback
2626
import java.util.Date
@@ -372,7 +372,7 @@ class ActivityLifecycleIntegrationTest {
372372
check {
373373
assertEquals(SpanStatus.OK, it.status)
374374
},
375-
anyOrNull<TraceState>(),
375+
anyOrNull<TraceContext>(),
376376
anyOrNull(),
377377
anyOrNull()
378378
)
@@ -395,7 +395,7 @@ class ActivityLifecycleIntegrationTest {
395395
check {
396396
assertEquals(SpanStatus.UNKNOWN_ERROR, it.status)
397397
},
398-
anyOrNull<TraceState>(),
398+
anyOrNull<TraceContext>(),
399399
anyOrNull(),
400400
anyOrNull()
401401
)
@@ -412,7 +412,7 @@ class ActivityLifecycleIntegrationTest {
412412
sut.onActivityCreated(activity, fixture.bundle)
413413
sut.onActivityPostResumed(activity)
414414

415-
verify(fixture.hub, never()).captureTransaction(any(), anyOrNull<TraceState>(), anyOrNull(), anyOrNull())
415+
verify(fixture.hub, never()).captureTransaction(any(), anyOrNull<TraceContext>(), anyOrNull(), anyOrNull())
416416
}
417417

418418
@Test
@@ -423,7 +423,7 @@ class ActivityLifecycleIntegrationTest {
423423
val activity = mock<Activity>()
424424
sut.onActivityPostResumed(activity)
425425

426-
verify(fixture.hub, never()).captureTransaction(any(), anyOrNull<TraceState>(), anyOrNull(), anyOrNull())
426+
verify(fixture.hub, never()).captureTransaction(any(), anyOrNull<TraceContext>(), anyOrNull(), anyOrNull())
427427
}
428428

429429
@Test
@@ -436,7 +436,7 @@ class ActivityLifecycleIntegrationTest {
436436
sut.onActivityCreated(activity, fixture.bundle)
437437
sut.onActivityDestroyed(activity)
438438

439-
verify(fixture.hub).captureTransaction(any(), anyOrNull<TraceState>(), anyOrNull(), anyOrNull())
439+
verify(fixture.hub).captureTransaction(any(), anyOrNull<TraceContext>(), anyOrNull(), anyOrNull())
440440
}
441441

442442
@Test
@@ -505,7 +505,7 @@ class ActivityLifecycleIntegrationTest {
505505
sut.onActivityCreated(mock(), mock())
506506

507507
sut.onActivityCreated(mock(), fixture.bundle)
508-
verify(fixture.hub).captureTransaction(any(), anyOrNull<TraceState>(), anyOrNull(), anyOrNull())
508+
verify(fixture.hub).captureTransaction(any(), anyOrNull<TraceContext>(), anyOrNull(), anyOrNull())
509509
}
510510

511511
@Test
@@ -518,7 +518,7 @@ class ActivityLifecycleIntegrationTest {
518518
sut.onActivityCreated(activity, mock())
519519
sut.onActivityResumed(activity)
520520

521-
verify(fixture.hub, never()).captureTransaction(any(), any<TraceState>(), anyOrNull())
521+
verify(fixture.hub, never()).captureTransaction(any(), any<TraceContext>(), anyOrNull())
522522
}
523523

524524
@Test
@@ -545,7 +545,7 @@ class ActivityLifecycleIntegrationTest {
545545
sut.onActivityCreated(activity, mock())
546546
sut.onActivityResumed(activity)
547547

548-
verify(fixture.hub).captureTransaction(any(), anyOrNull<TraceState>(), anyOrNull(), anyOrNull())
548+
verify(fixture.hub).captureTransaction(any(), anyOrNull<TraceContext>(), anyOrNull(), anyOrNull())
549549
}
550550

551551
@Test

sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class SentryOkHttpInterceptor(
4040
span.toSentryTrace().let {
4141
requestBuilder.addHeader(it.name, it.value)
4242
}
43-
span.toTraceStateHeader()?.let {
43+
span.toBaggageHeader()?.let {
4444
requestBuilder.addHeader(it.name, it.value)
4545
}
4646
}

sentry-android-okhttp/src/test/java/io/sentry/android/okhttp/SentryOkHttpInterceptorTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import com.nhaarman.mockitokotlin2.check
77
import com.nhaarman.mockitokotlin2.mock
88
import com.nhaarman.mockitokotlin2.verify
99
import com.nhaarman.mockitokotlin2.whenever
10+
import io.sentry.BaggageHeader
1011
import io.sentry.Breadcrumb
1112
import io.sentry.IHub
1213
import io.sentry.SentryOptions
1314
import io.sentry.SentryTraceHeader
1415
import io.sentry.SentryTracer
1516
import io.sentry.SpanStatus
16-
import io.sentry.TraceStateHeader
1717
import io.sentry.TransactionContext
1818
import okhttp3.Interceptor
1919
import okhttp3.MediaType.Companion.toMediaType
@@ -97,7 +97,7 @@ class SentryOkHttpInterceptorTest {
9797
sut.newCall(getRequest()).execute()
9898
val recorderRequest = fixture.server.takeRequest()
9999
assertNotNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER])
100-
assertNotNull(recorderRequest.headers[TraceStateHeader.TRACE_STATE_HEADER])
100+
assertNotNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER])
101101
}
102102

103103
@Test
@@ -106,7 +106,7 @@ class SentryOkHttpInterceptorTest {
106106
sut.newCall(Request.Builder().get().url(fixture.server.url("/hello")).build()).execute()
107107
val recorderRequest = fixture.server.takeRequest()
108108
assertNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER])
109-
assertNull(recorderRequest.headers[TraceStateHeader.TRACE_STATE_HEADER])
109+
assertNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER])
110110
}
111111

112112
@Test
@@ -115,7 +115,7 @@ class SentryOkHttpInterceptorTest {
115115
sut.newCall(getRequest()).execute()
116116
val recorderRequest = fixture.server.takeRequest()
117117
assertNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER])
118-
assertNull(recorderRequest.headers[TraceStateHeader.TRACE_STATE_HEADER])
118+
assertNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER])
119119
}
120120

121121
@Test

sentry-apollo/src/main/java/io/sentry/apollo/SentryApolloInterceptor.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ class SentryApolloInterceptor(
3939
val sentryTraceHeader = span.toSentryTrace()
4040

4141
// we have no access to URI, no way to verify tracing origins
42-
val headers = request.requestHeaders.toBuilder().addHeader(sentryTraceHeader.name, sentryTraceHeader.value).build()
42+
val requestHeaderBuilder = request.requestHeaders.toBuilder()
43+
requestHeaderBuilder.addHeader(sentryTraceHeader.name, sentryTraceHeader.value)
44+
span.toBaggageHeader()?.let {
45+
requestHeaderBuilder.addHeader(it.name, it.value)
46+
}
47+
val headers = requestHeaderBuilder.build()
4348
val requestWithHeader = request.toBuilder().requestHeaders(headers).build()
4449
span.setData("operationId", requestWithHeader.operation.operationId())
4550
span.setData("variables", requestWithHeader.operation.variables().valueMap().toString())

sentry-apollo/src/test/java/io/sentry/apollo/SentryApolloInterceptorTest.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import io.sentry.SentryOptions
1515
import io.sentry.SentryTraceHeader
1616
import io.sentry.SentryTracer
1717
import io.sentry.SpanStatus
18-
import io.sentry.TraceState
18+
import io.sentry.TraceContext
1919
import io.sentry.TransactionContext
2020
import io.sentry.protocol.SentryTransaction
2121
import kotlinx.coroutines.launch
@@ -85,7 +85,7 @@ class SentryApolloInterceptorTest {
8585
assertTransactionDetails(it)
8686
assertEquals(SpanStatus.OK, it.spans.first().status)
8787
},
88-
anyOrNull<TraceState>(),
88+
anyOrNull<TraceContext>(),
8989
anyOrNull(),
9090
anyOrNull()
9191
)
@@ -100,7 +100,7 @@ class SentryApolloInterceptorTest {
100100
assertTransactionDetails(it)
101101
assertEquals(SpanStatus.PERMISSION_DENIED, it.spans.first().status)
102102
},
103-
anyOrNull<TraceState>(),
103+
anyOrNull<TraceContext>(),
104104
anyOrNull(),
105105
anyOrNull()
106106
)
@@ -115,7 +115,7 @@ class SentryApolloInterceptorTest {
115115
assertTransactionDetails(it)
116116
assertEquals(SpanStatus.INTERNAL_ERROR, it.spans.first().status)
117117
},
118-
anyOrNull<TraceState>(),
118+
anyOrNull<TraceContext>(),
119119
anyOrNull(),
120120
anyOrNull()
121121
)
@@ -151,7 +151,7 @@ class SentryApolloInterceptorTest {
151151
val httpClientSpan = it.spans.first()
152152
assertEquals("overwritten description", httpClientSpan.description)
153153
},
154-
anyOrNull<TraceState>(),
154+
anyOrNull<TraceContext>(),
155155
anyOrNull(),
156156
anyOrNull()
157157
)
@@ -167,7 +167,7 @@ class SentryApolloInterceptorTest {
167167
check {
168168
assertEquals(1, it.spans.size)
169169
},
170-
anyOrNull<TraceState>(),
170+
anyOrNull<TraceContext>(),
171171
anyOrNull(),
172172
anyOrNull()
173173
)

sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
import feign.Client;
77
import feign.Request;
88
import feign.Response;
9+
import io.sentry.BaggageHeader;
910
import io.sentry.Breadcrumb;
1011
import io.sentry.Hint;
1112
import io.sentry.IHub;
1213
import io.sentry.ISpan;
1314
import io.sentry.SentryTraceHeader;
1415
import io.sentry.SpanStatus;
16+
import io.sentry.TracingOrigins;
1517
import io.sentry.util.Objects;
1618
import java.io.IOException;
1719
import java.util.Collection;
@@ -47,11 +49,20 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O
4749
}
4850

4951
ISpan span = activeSpan.startChild("http.client");
50-
span.setDescription(request.httpMethod().name() + " " + request.url());
52+
String url = request.url();
53+
span.setDescription(request.httpMethod().name() + " " + url);
5154

52-
final SentryTraceHeader sentryTraceHeader = span.toSentryTrace();
5355
final RequestWrapper requestWrapper = new RequestWrapper(request);
54-
requestWrapper.header(sentryTraceHeader.getName(), sentryTraceHeader.getValue());
56+
57+
if (TracingOrigins.contain(hub.getOptions().getTracingOrigins(), url)) {
58+
final SentryTraceHeader sentryTraceHeader = span.toSentryTrace();
59+
final @Nullable BaggageHeader baggageHeader = span.toBaggageHeader();
60+
requestWrapper.header(sentryTraceHeader.getName(), sentryTraceHeader.getValue());
61+
if (baggageHeader != null) {
62+
requestWrapper.header(baggageHeader.getName(), baggageHeader.getValue());
63+
}
64+
}
65+
5566
try {
5667
response = delegate.execute(requestWrapper.build(), options);
5768
// handles both success and error responses

sentry-openfeign/src/test/kotlin/io/sentry/openfeign/SentryFeignClientTest.kt

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import feign.Client
1010
import feign.Feign
1111
import feign.FeignException
1212
import feign.RequestLine
13+
import io.sentry.BaggageHeader
1314
import io.sentry.Breadcrumb
1415
import io.sentry.IHub
1516
import io.sentry.SentryOptions
@@ -19,6 +20,7 @@ import io.sentry.SpanStatus
1920
import io.sentry.TransactionContext
2021
import okhttp3.mockwebserver.MockResponse
2122
import okhttp3.mockwebserver.MockWebServer
23+
import kotlin.test.BeforeTest
2224
import kotlin.test.Test
2325
import kotlin.test.assertEquals
2426
import kotlin.test.assertFalse
@@ -33,9 +35,10 @@ class SentryFeignClientTest {
3335
val hub = mock<IHub>()
3436
val server = MockWebServer()
3537
val sentryTracer = SentryTracer(TransactionContext("name", "op"), hub)
38+
val sentryOptions = SentryOptions()
3639

3740
init {
38-
whenever(hub.options).thenReturn(SentryOptions())
41+
whenever(hub.options).thenReturn(sentryOptions)
3942
}
4043

4144
fun getSut(
@@ -67,22 +70,45 @@ class SentryFeignClientTest {
6770
}
6871
}
6972

70-
private val fixture = Fixture()
73+
private lateinit var fixture: Fixture
74+
75+
@BeforeTest
76+
fun setup() {
77+
fixture = Fixture()
78+
}
7179

7280
@Test
7381
fun `when there is an active span, adds sentry trace header to the request`() {
82+
fixture.sentryOptions.isTraceSampling = true
83+
fixture.sentryOptions.dsn = "https://[email protected]/proj"
7484
val sut = fixture.getSut()
7585
sut.getOk()
7686
val recorderRequest = fixture.server.takeRequest()
7787
assertNotNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER])
88+
assertNotNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER])
7889
}
7990

8091
@Test
8192
fun `when there is no active span, does not add sentry trace header to the request`() {
93+
fixture.sentryOptions.isTraceSampling = true
94+
fixture.sentryOptions.dsn = "https://[email protected]/proj"
8295
val sut = fixture.getSut(isSpanActive = false)
8396
sut.getOk()
8497
val recorderRequest = fixture.server.takeRequest()
8598
assertNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER])
99+
assertNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER])
100+
}
101+
102+
@Test
103+
fun `when request url not in tracing origins, does not add sentry trace header to the request`() {
104+
fixture.sentryOptions.addTracingOrigin("http://some-other-url.sentry.io")
105+
fixture.sentryOptions.isTraceSampling = true
106+
fixture.sentryOptions.dsn = "https://[email protected]/proj"
107+
val sut = fixture.getSut()
108+
sut.getOk()
109+
val recorderRequest = fixture.server.takeRequest()
110+
assertNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER])
111+
assertNull(recorderRequest.headers[BaggageHeader.BAGGAGE_HEADER])
86112
}
87113

88114
@Test

sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientWebRequestFilter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static io.sentry.TypeCheckHint.SPRING_EXCHANGE_FILTER_RESPONSE;
55

66
import com.jakewharton.nopen.annotation.Open;
7+
import io.sentry.BaggageHeader;
78
import io.sentry.Breadcrumb;
89
import io.sentry.Hint;
910
import io.sentry.IHub;
@@ -41,11 +42,15 @@ public SentrySpanClientWebRequestFilter(final @NotNull IHub hub) {
4142
span.setDescription(request.method().name() + " " + request.url());
4243

4344
final SentryTraceHeader sentryTraceHeader = span.toSentryTrace();
45+
final @Nullable BaggageHeader baggageHeader = span.toBaggageHeader();
4446

4547
final ClientRequest.Builder requestBuilder = ClientRequest.from(request);
4648

4749
if (TracingOrigins.contain(hub.getOptions().getTracingOrigins(), request.url())) {
4850
requestBuilder.header(sentryTraceHeader.getName(), sentryTraceHeader.getValue());
51+
if (baggageHeader != null) {
52+
requestBuilder.header(baggageHeader.getName(), baggageHeader.getValue());
53+
}
4954
}
5055

5156
final ClientRequest clientRequestWithSentryTraceHeader = requestBuilder.build();

0 commit comments

Comments
 (0)