Skip to content

Commit 34ad29e

Browse files
committed
Merge branch 'main' into feat/poc-capture-otel-events
2 parents 5e67b8b + 0584f7e commit 34ad29e

File tree

37 files changed

+1300
-109
lines changed

37 files changed

+1300
-109
lines changed

CHANGELOG.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,37 @@
11
# Changelog
22

3-
## Unreleased
3+
## 8.3.0
44

55
### Features
66

7+
- Add HTTP server request headers from OpenTelemetry span attributes to sentry `request` in payload ([#4102](https://github.com/getsentry/sentry-java/pull/4102))
8+
- You have to explicitly enable each header by adding it to the [OpenTelemetry config](https://opentelemetry.io/docs/zero-code/java/agent/instrumentation/http/#capturing-http-request-and-response-headers)
9+
- Please only enable headers you actually want to send to Sentry. Some may contain sensitive data like PII, cookies, tokens etc.
10+
- We are no longer adding request/response headers to `contexts/otel/attributes` of the event.
711
- The `ignoredErrors` option is now configurable via the manifest property `io.sentry.traces.ignored-errors` ([#4178](https://github.com/getsentry/sentry-java/pull/4178))
812
- A list of active Spring profiles is attached to payloads sent to Sentry (errors, traces, etc.) and displayed in the UI when using our Spring or Spring Boot integrations ([#4147](https://github.com/getsentry/sentry-java/pull/4147))
913
- This consists of an empty list when only the default profile is active
1014
- Added `enableTraceIdGeneration` to the AndroidOptions. This allows Hybrid SDKs to "freeze" and control the trace and connect errors on different layers of the application ([4188](https://github.com/getsentry/sentry-java/pull/4188))
1115
- Move to a single NetworkCallback listener to reduce number of IPC calls on Android ([#4164](https://github.com/getsentry/sentry-java/pull/4164))
1216
- Add GraphQL Apollo Kotlin 4 integration ([#4166](https://github.com/getsentry/sentry-java/pull/4166))
17+
- Add support for async dispatch requests to Spring Boot 2 and 3 ([#3983](https://github.com/getsentry/sentry-java/pull/3983))
18+
- To enable it, please set `sentry.keep-transactions-open-for-async-responses=true` in `application.properties` or `sentry.keepTransactionsOpenForAsyncResponses: true` in `application.yml`
19+
- Add constructor to JUL `SentryHandler` for disabling external config ([#4208](https://github.com/getsentry/sentry-java/pull/4208))
1320

1421
### Fixes
1522

23+
- Filter strings that cannot be parsed as Regex no longer cause an SDK crash ([#4213](https://github.com/getsentry/sentry-java/pull/4213))
24+
- This was the case e.g. for `ignoredErrors`, `ignoredTransactions` and `ignoredCheckIns`
25+
- We now simply don't use such strings for Regex matching and only use them for String comparison
1626
- `SentryOptions.setTracePropagationTargets` is no longer marked internal ([#4170](https://github.com/getsentry/sentry-java/pull/4170))
27+
- Session Replay: Fix crash when a navigation breadcrumb does not have "to" destination ([#4185](https://github.com/getsentry/sentry-java/pull/4185))
28+
- Session Replay: Cap video segment duration to maximum 5 minutes to prevent endless video encoding in background ([#4185](https://github.com/getsentry/sentry-java/pull/4185))
29+
- Check `tracePropagationTargets` in OpenTelemetry propagator ([#4191](https://github.com/getsentry/sentry-java/pull/4191))
30+
- If a URL can be retrieved from OpenTelemetry span attributes, we check it against `tracePropagationTargets` before attaching `sentry-trace` and `baggage` headers to outgoing requests
31+
- If no URL can be retrieved we always attach the headers
32+
- Fix `ignoredErrors`, `ignoredTransactions` and `ignoredCheckIns` being unset by external options like `sentry.properties` or ENV vars ([#4207](https://github.com/getsentry/sentry-java/pull/4207))
33+
- Whenever parsing of external options was enabled (`enableExternalConfiguration`), which is the default for many integrations, the values set on `SentryOptions` passed to `Sentry.init` would be lost
34+
- Even if the value was not set in any external configuration it would still be set to an empty list
1735

1836
### Behavioural Changes
1937

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ org.gradle.workers.max=2
1414
android.useAndroidX=true
1515

1616
# Release information
17-
versionName=8.2.0
17+
versionName=8.3.0
1818

1919
# Override the SDK name on native crashes on Android
2020
sentryAndroidSdkName=sentry.native.android

sentry-android-replay/src/main/java/io/sentry/android/replay/capture/CaptureStrategy.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ internal interface CaptureStrategy {
5858
companion object {
5959
private const val BREADCRUMB_START_OFFSET = 100L
6060

61+
// 5 minutes, otherwise relay will just drop it. Can prevent the case where the device
62+
// time is wrong and the segment is too long.
63+
private const val MAX_SEGMENT_DURATION = 1000L * 60 * 5
64+
6165
fun createSegment(
6266
scopes: IScopes?,
6367
options: SentryOptions,
@@ -76,7 +80,7 @@ internal interface CaptureStrategy {
7680
events: Deque<RRWebEvent>
7781
): ReplaySegment {
7882
val generatedVideo = cache?.createVideoOf(
79-
duration,
83+
minOf(duration, MAX_SEGMENT_DURATION),
8084
currentSegmentTimestamp.time,
8185
segmentId,
8286
height,
@@ -179,7 +183,9 @@ internal interface CaptureStrategy {
179183
recordingPayload += rrwebEvent
180184

181185
// fill in the urls array from navigation breadcrumbs
182-
if ((rrwebEvent as? RRWebBreadcrumbEvent)?.category == "navigation") {
186+
if ((rrwebEvent as? RRWebBreadcrumbEvent)?.category == "navigation" &&
187+
rrwebEvent.data?.getOrElse("to", { null }) is String
188+
) {
183189
urls.add(rrwebEvent.data!!["to"] as String)
184190
}
185191
}

sentry-android-replay/src/test/java/io/sentry/android/replay/capture/SessionCaptureStrategyTest.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,30 @@ class SessionCaptureStrategyTest {
336336
)
337337
}
338338

339+
@Test
340+
fun `does not throw when navigation destination is not a String`() {
341+
val now =
342+
System.currentTimeMillis() + (fixture.options.sessionReplay.sessionSegmentDuration * 5)
343+
val strategy = fixture.getSut(dateProvider = { now })
344+
strategy.start(fixture.recorderConfig)
345+
346+
fixture.scope.addBreadcrumb(Breadcrumb().apply { category = "navigation" })
347+
348+
strategy.onScreenshotRecorded(mock<Bitmap>()) {}
349+
350+
verify(fixture.scopes).captureReplay(
351+
check {
352+
assertNull(it.urls?.firstOrNull())
353+
},
354+
check {
355+
val breadcrumbEvents =
356+
it.replayRecording?.payload?.filterIsInstance<RRWebBreadcrumbEvent>()
357+
assertEquals("navigation", breadcrumbEvents?.first()?.category)
358+
assertNull(breadcrumbEvents?.first()?.data?.get("to"))
359+
}
360+
)
361+
}
362+
339363
@Test
340364
fun `sets screen from scope as replay url`() {
341365
fixture.scope.screen = "MainActivity"

sentry-jul/api/sentry-jul.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class io/sentry/jul/SentryHandler : java/util/logging/Handler {
88
public static final field THREAD_ID Ljava/lang/String;
99
public fun <init> ()V
1010
public fun <init> (Lio/sentry/SentryOptions;)V
11+
public fun <init> (Lio/sentry/SentryOptions;Z)V
1112
public fun close ()V
1213
public fun flush ()V
1314
public fun getMinimumBreadcrumbLevel ()Ljava/util/logging/Level;

sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public class SentryHandler extends Handler {
5151

5252
/** Creates an instance of SentryHandler. */
5353
public SentryHandler() {
54-
this(new SentryOptions(), true);
54+
this(new SentryOptions());
5555
}
5656

5757
/**
@@ -60,17 +60,32 @@ public SentryHandler() {
6060
* @param options the SentryOptions
6161
*/
6262
public SentryHandler(final @NotNull SentryOptions options) {
63-
this(options, true);
63+
this(options, true, true);
64+
}
65+
66+
/**
67+
* Creates an instance of SentryHandler.
68+
*
69+
* @param options the SentryOptions
70+
* @param enableExternalConfiguration whether external options like sentry.properties and ENV vars
71+
* should be parsed
72+
*/
73+
public SentryHandler(
74+
final @NotNull SentryOptions options, final boolean enableExternalConfiguration) {
75+
this(options, true, enableExternalConfiguration);
6476
}
6577

6678
/** Creates an instance of SentryHandler. */
6779
@TestOnly
68-
SentryHandler(final @NotNull SentryOptions options, final boolean configureFromLogManager) {
80+
SentryHandler(
81+
final @NotNull SentryOptions options,
82+
final boolean configureFromLogManager,
83+
final boolean enableExternalConfiguration) {
6984
setFilter(new DropSentryFilter());
7085
if (configureFromLogManager) {
7186
retrieveProperties();
7287
}
73-
options.setEnableExternalConfiguration(true);
88+
options.setEnableExternalConfiguration(enableExternalConfiguration);
7489
options.setInitPriority(InitPriority.LOWEST);
7590
options.setSdkVersion(createSdkVersion(options));
7691
Sentry.init(options);

sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class SentryHandlerTest {
3636
options.setTransportFactory { _, _ -> transport }
3737
contextTags?.forEach { options.addContextTag(it) }
3838
logger = Logger.getLogger("jul.SentryHandlerTest")
39-
handler = SentryHandler(options, configureWithLogManager)
39+
handler = SentryHandler(options, configureWithLogManager, true)
4040
handler.setMinimumBreadcrumbLevel(minimumBreadcrumbLevel)
4141
handler.setMinimumEventLevel(minimumEventLevel)
4242
handler.level = Level.ALL

sentry-opentelemetry/sentry-opentelemetry-bootstrap/api/sentry-opentelemetry-bootstrap.api

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
public abstract interface class io/sentry/opentelemetry/IOtelSpanWrapper : io/sentry/ISpan {
22
public abstract fun getData ()Ljava/util/Map;
33
public abstract fun getMeasurements ()Ljava/util/Map;
4+
public abstract fun getOpenTelemetrySpanAttributes ()Lio/opentelemetry/api/common/Attributes;
45
public abstract fun getScopes ()Lio/sentry/IScopes;
56
public abstract fun getTags ()Ljava/util/Map;
67
public abstract fun getTraceId ()Lio/sentry/protocol/SentryId;
@@ -51,6 +52,7 @@ public final class io/sentry/opentelemetry/OtelStrongRefSpanWrapper : io/sentry/
5152
public fun getDescription ()Ljava/lang/String;
5253
public fun getFinishDate ()Lio/sentry/SentryDate;
5354
public fun getMeasurements ()Ljava/util/Map;
55+
public fun getOpenTelemetrySpanAttributes ()Lio/opentelemetry/api/common/Attributes;
5456
public fun getOperation ()Ljava/lang/String;
5557
public fun getSamplingDecision ()Lio/sentry/TracesSamplingDecision;
5658
public fun getScopes ()Lio/sentry/IScopes;
@@ -177,6 +179,7 @@ public final class io/sentry/opentelemetry/SentryOtelThreadLocalStorage : io/ope
177179
}
178180

179181
public final class io/sentry/opentelemetry/SentryWeakSpanStorage {
182+
public fun clear ()V
180183
public static fun getInstance ()Lio/sentry/opentelemetry/SentryWeakSpanStorage;
181184
public fun getSentrySpan (Lio/opentelemetry/api/trace/SpanContext;)Lio/sentry/opentelemetry/IOtelSpanWrapper;
182185
public fun storeSentrySpan (Lio/opentelemetry/api/trace/SpanContext;Lio/sentry/opentelemetry/IOtelSpanWrapper;)V

sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/IOtelSpanWrapper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry.opentelemetry;
22

3+
import io.opentelemetry.api.common.Attributes;
34
import io.opentelemetry.context.Context;
45
import io.sentry.IScopes;
56
import io.sentry.ISpan;
@@ -47,4 +48,8 @@ public interface IOtelSpanWrapper extends ISpan {
4748

4849
@NotNull
4950
Context storeInContext(Context context);
51+
52+
@ApiStatus.Internal
53+
@Nullable
54+
Attributes getOpenTelemetrySpanAttributes();
5055
}

sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelStrongRefSpanWrapper.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry.opentelemetry;
22

3+
import io.opentelemetry.api.common.Attributes;
34
import io.opentelemetry.api.trace.Span;
45
import io.opentelemetry.context.Context;
56
import io.sentry.BaggageHeader;
@@ -303,4 +304,10 @@ public void setContext(@NotNull String key, @NotNull Object context) {
303304
public @NotNull ISentryLifecycleToken makeCurrent() {
304305
return delegate.makeCurrent();
305306
}
307+
308+
@ApiStatus.Internal
309+
@Override
310+
public @Nullable Attributes getOpenTelemetrySpanAttributes() {
311+
return delegate.getOpenTelemetrySpanAttributes();
312+
}
306313
}

0 commit comments

Comments
 (0)