Skip to content

Commit 046fb12

Browse files
authored
Merge branch 'main' into markushi/fix/determine-app-start-type-via-content-provider-main
2 parents 7cceb9a + e5b840c commit 046fb12

File tree

16 files changed

+628
-77
lines changed

16 files changed

+628
-77
lines changed

CHANGELOG.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
### Fixes
66

7+
- Ensure app start type is set, even when ActivityLifecycleIntegration is not running ([#4250](https://github.com/getsentry/sentry-java/pull/4250))
8+
9+
## 8.4.0
10+
11+
### Fixes
12+
713
- The SDK now handles `null` on many APIs instead of expecting a non `null` value ([#4245](https://github.com/getsentry/sentry-java/pull/4245))
814
- Certain APIs like `setTag`, `setData`, `setExtra`, `setContext` previously caused a `NullPointerException` when invoked with either `null` key or value.
915
- The SDK now tries to have a sane fallback when `null` is passed and no longer throws `NullPointerException`
@@ -13,7 +19,15 @@
1319
- Add support for setting in-app-includes/in-app-excludes via AndroidManifest.xml ([#4240](https://github.com/getsentry/sentry-java/pull/4240))
1420
- Modifications to OkHttp requests are now properly propagated to the affected span / breadcrumbs ([#4238](https://github.com/getsentry/sentry-java/pull/4238))
1521
- Please ensure the SentryOkHttpInterceptor is added last to your OkHttpClient, as otherwise changes to the `Request` by subsequent interceptors won't be considered
16-
- Ensure app start type is set, even when ActivityLifecycleIntegration is not running ([#4250](https://github.com/getsentry/sentry-java/pull/4250))
22+
- Fix "class ch.qos.logback.classic.spi.ThrowableProxyVO cannot be cast to class ch.qos.logback.classic.spi.ThrowableProxy" ([#4206](https://github.com/getsentry/sentry-java/pull/4206))
23+
- In this case we cannot report the `Throwable` to Sentry as it's not available
24+
- If you are using OpenTelemetry v1 `OpenTelemetryAppender`, please consider upgrading to v2
25+
- Pass OpenTelemetry span attributes into TracesSampler callback ([#4253](https://github.com/getsentry/sentry-java/pull/4253))
26+
- `SamplingContext` now has a `getAttribute` method that grants access to OpenTelemetry span attributes via their String key (e.g. `http.request.method`)
27+
- Fix AbstractMethodError when using SentryTraced for Jetpack Compose ([#4255](https://github.com/getsentry/sentry-java/pull/4255))
28+
- Assume `http.client` for span `op` if not a root span ([#4257](https://github.com/getsentry/sentry-java/pull/4257))
29+
- Avoid unnecessary copies when using `CopyOnWriteArrayList` ([#4247](https://github.com/getsentry/sentry-java/pull/4247))
30+
- This affects in particular `SentryTracer.getLatestActiveSpan` which would have previously copied all child span references. This may have caused `OutOfMemoryError` on certain devices due to high frequency of calling the method.
1731

1832
### Features
1933

@@ -477,6 +491,24 @@ If you have been using `8.0.0-rc.4` of the Java SDK, here's the new changes that
477491
- We are planning to improve this in the future but opted for this fix first.
478492
- Fix swallow NDK loadLibrary errors ([#4082](https://github.com/getsentry/sentry-java/pull/4082))
479493

494+
## 7.22.1
495+
496+
### Fixes
497+
498+
- Fix Ensure app start type is set, even when ActivityLifecycleIntegration is not running ([#4216](https://github.com/getsentry/sentry-java/pull/4216))
499+
- Fix properly reset application/content-provider timespans for warm app starts ([#4244](https://github.com/getsentry/sentry-java/pull/4244))
500+
501+
## 7.22.0
502+
503+
### Fixes
504+
505+
- Session Replay: Fix various crashes and issues ([#4135](https://github.com/getsentry/sentry-java/pull/4135))
506+
- Fix `FileNotFoundException` when trying to read/write `.ongoing_segment` file
507+
- Fix `IllegalStateException` when registering `onDrawListener`
508+
- Fix SIGABRT native crashes on Motorola devices when encoding a video
509+
- (Jetpack Compose) Modifier.sentryTag now uses Modifier.Node ([#4029](https://github.com/getsentry/sentry-java/pull/4029))
510+
- This allows Composables that use this modifier to be skippable
511+
480512
## 7.21.0
481513

482514
### Fixes

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.3.0
17+
versionName=8.4.0
1818

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

sentry-compose/src/androidMain/kotlin/io/sentry/compose/SentryModifier.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ public object SentryModifier {
5151
Modifier.Node(),
5252
SemanticsModifierNode {
5353

54+
override val shouldClearDescendantSemantics: Boolean
55+
get() = false
56+
57+
override val shouldMergeDescendantSemantics: Boolean
58+
get() = false
59+
5460
override fun SemanticsPropertyReceiver.applySemantics() {
5561
this[SentryTag] = tag
5662
}

sentry-logback/src/main/java/io/sentry/logback/SentryAppender.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,16 @@ protected void append(@NotNull ILoggingEvent eventObject) {
110110
event.setLogger(loggingEvent.getLoggerName());
111111
event.setLevel(formatLevel(loggingEvent.getLevel()));
112112

113-
final ThrowableProxy throwableInformation = (ThrowableProxy) loggingEvent.getThrowableProxy();
114-
if (throwableInformation != null) {
115-
final Mechanism mechanism = new Mechanism();
116-
mechanism.setType(MECHANISM_TYPE);
117-
final Throwable mechanismException =
118-
new ExceptionMechanismException(
119-
mechanism, throwableInformation.getThrowable(), Thread.currentThread());
120-
event.setThrowable(mechanismException);
113+
if (loggingEvent.getThrowableProxy() instanceof ThrowableProxy) {
114+
final ThrowableProxy throwableInformation = (ThrowableProxy) loggingEvent.getThrowableProxy();
115+
if (throwableInformation != null) {
116+
final Mechanism mechanism = new Mechanism();
117+
mechanism.setType(MECHANISM_TYPE);
118+
final Throwable mechanismException =
119+
new ExceptionMechanismException(
120+
mechanism, throwableInformation.getThrowable(), Thread.currentThread());
121+
event.setThrowable(mechanismException);
122+
}
121123
}
122124

123125
if (loggingEvent.getThreadName() != null) {

sentry-logback/src/test/kotlin/io/sentry/logback/SentryAppenderTest.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import ch.qos.logback.classic.Level
44
import ch.qos.logback.classic.LoggerContext
55
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
66
import ch.qos.logback.classic.spi.ILoggingEvent
7+
import ch.qos.logback.classic.spi.LoggingEvent
8+
import ch.qos.logback.classic.spi.LoggingEventVO
9+
import ch.qos.logback.classic.spi.ThrowableProxy
710
import ch.qos.logback.core.encoder.Encoder
811
import ch.qos.logback.core.encoder.EncoderBase
912
import ch.qos.logback.core.status.Status
@@ -536,4 +539,24 @@ class SentryAppenderTest {
536539
assertTrue(Sentry.isEnabled())
537540
System.clearProperty("sentry.dsn")
538541
}
542+
543+
@Test
544+
fun `does not crash on ThrowableProxyVO`() {
545+
fixture = Fixture()
546+
val throwableProxy = ThrowableProxy(RuntimeException("hello proxy throwable"))
547+
val loggingEvent = LoggingEvent()
548+
loggingEvent.level = Level.ERROR
549+
loggingEvent.setThrowableProxy(throwableProxy)
550+
val loggingEventVO = LoggingEventVO.build(loggingEvent)
551+
552+
fixture.appender.append(loggingEventVO)
553+
554+
verify(fixture.transport).send(
555+
checkEvent { event ->
556+
assertEquals(SentryLevel.ERROR, event.level)
557+
assertNull(event.exceptions)
558+
},
559+
anyOrNull()
560+
)
561+
}
539562
}

sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySampler.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import io.sentry.TransactionContext;
2424
import io.sentry.clientreport.DiscardReason;
2525
import io.sentry.protocol.SentryId;
26+
import java.util.HashMap;
2627
import java.util.List;
28+
import java.util.Map;
2729
import org.jetbrains.annotations.NotNull;
2830
import org.jetbrains.annotations.Nullable;
2931

@@ -64,13 +66,15 @@ public SamplingResult shouldSample(
6466
if (samplingDecision != null) {
6567
return new SentrySamplingResult(samplingDecision);
6668
} else {
67-
return handleRootOtelSpan(traceId, parentContext);
69+
return handleRootOtelSpan(traceId, parentContext, attributes);
6870
}
6971
}
7072
}
7173

7274
private @NotNull SamplingResult handleRootOtelSpan(
73-
final @NotNull String traceId, final @NotNull Context parentContext) {
75+
final @NotNull String traceId,
76+
final @NotNull Context parentContext,
77+
final @NotNull Attributes attributes) {
7478
if (!scopes.getOptions().isTracingEnabled()) {
7579
return SamplingResult.create(SamplingDecision.RECORD_ONLY);
7680
}
@@ -96,7 +100,11 @@ public SamplingResult shouldSample(
96100
.getOptions()
97101
.getInternalTracesSampler()
98102
.sample(
99-
new SamplingContext(transactionContext, null, propagationContext.getSampleRand()));
103+
new SamplingContext(
104+
transactionContext,
105+
null,
106+
propagationContext.getSampleRand(),
107+
toMapWithStringKeys(attributes)));
100108

101109
if (!sentryDecision.getSampled()) {
102110
scopes
@@ -135,6 +143,22 @@ public SamplingResult shouldSample(
135143
}
136144
}
137145

146+
private @NotNull Map<String, Object> toMapWithStringKeys(final @NotNull Attributes attributes) {
147+
final @NotNull Map<String, Object> mapWithStringKeys = new HashMap<>(attributes.size());
148+
149+
if (attributes != null) {
150+
attributes.forEach(
151+
(key, value) -> {
152+
if (key != null) {
153+
final @NotNull String stringKey = key.getKey();
154+
mapWithStringKeys.put(stringKey, value);
155+
}
156+
});
157+
}
158+
159+
return mapWithStringKeys;
160+
}
161+
138162
@Override
139163
public String getDescription() {
140164
return "SentrySampler";

sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SpanDescriptionExtractor.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,16 @@ public final class SpanDescriptionExtractor {
1818
@SuppressWarnings("deprecation")
1919
public @NotNull OtelSpanInfo extractSpanInfo(
2020
final @NotNull SpanData otelSpan, final @Nullable IOtelSpanWrapper sentrySpan) {
21-
if (!isInternalSpanKind(otelSpan)) {
22-
final @NotNull Attributes attributes = otelSpan.getAttributes();
23-
24-
final @Nullable String httpMethod = attributes.get(HttpAttributes.HTTP_REQUEST_METHOD);
25-
if (httpMethod != null) {
26-
return descriptionForHttpMethod(otelSpan, httpMethod);
27-
}
21+
final @NotNull Attributes attributes = otelSpan.getAttributes();
2822

29-
final @Nullable String httpRequestMethod = attributes.get(HttpAttributes.HTTP_REQUEST_METHOD);
30-
if (httpRequestMethod != null) {
31-
return descriptionForHttpMethod(otelSpan, httpRequestMethod);
32-
}
23+
final @Nullable String httpMethod = attributes.get(HttpAttributes.HTTP_REQUEST_METHOD);
24+
if (httpMethod != null) {
25+
return descriptionForHttpMethod(otelSpan, httpMethod);
26+
}
3327

34-
final @Nullable String dbSystem = attributes.get(DbIncubatingAttributes.DB_SYSTEM);
35-
if (dbSystem != null) {
36-
return descriptionForDbSystem(otelSpan);
37-
}
28+
final @Nullable String dbSystem = attributes.get(DbIncubatingAttributes.DB_SYSTEM);
29+
if (dbSystem != null) {
30+
return descriptionForDbSystem(otelSpan);
3831
}
3932

4033
final @NotNull String name = otelSpan.getName();
@@ -44,10 +37,6 @@ public final class SpanDescriptionExtractor {
4437
return new OtelSpanInfo(name, description, TransactionNameSource.CUSTOM);
4538
}
4639

47-
private boolean isInternalSpanKind(final @NotNull SpanData otelSpan) {
48-
return SpanKind.INTERNAL.equals(otelSpan.getKind());
49-
}
50-
5140
@SuppressWarnings("deprecation")
5241
private OtelSpanInfo descriptionForHttpMethod(
5342
final @NotNull SpanData otelSpan, final @NotNull String httpMethod) {
@@ -60,6 +49,12 @@ private OtelSpanInfo descriptionForHttpMethod(
6049
opBuilder.append(".client");
6150
} else if (SpanKind.SERVER.equals(kind)) {
6251
opBuilder.append(".server");
52+
} else {
53+
// we cannot be certain that a root span is a server span as it might simply be a client span
54+
// without parent
55+
if (!isRootSpan(otelSpan)) {
56+
opBuilder.append(".client");
57+
}
6358
}
6459
final @Nullable String httpTarget = attributes.get(HttpIncubatingAttributes.HTTP_TARGET);
6560
final @Nullable String httpRoute = attributes.get(HttpAttributes.HTTP_ROUTE);
@@ -92,6 +87,10 @@ private OtelSpanInfo descriptionForHttpMethod(
9287
return new OtelSpanInfo(op, description, transactionNameSource);
9388
}
9489

90+
private static boolean isRootSpan(SpanData otelSpan) {
91+
return !otelSpan.getParentSpanContext().isValid() || otelSpan.getParentSpanContext().isRemote();
92+
}
93+
9594
@SuppressWarnings("deprecation")
9695
private OtelSpanInfo descriptionForDbSystem(final @NotNull SpanData otelSpan) {
9796
final @NotNull Attributes attributes = otelSpan.getAttributes();

0 commit comments

Comments
 (0)