Skip to content

Commit a703a6e

Browse files
authored
Merge branch 'main' into rz/fix/previous-session-flush-wait
2 parents f636ca7 + e2b7f44 commit a703a6e

File tree

25 files changed

+330
-72
lines changed

25 files changed

+330
-72
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
- Session Replay: Use main thread looper to schedule replay capture ([#4542](https://github.com/getsentry/sentry-java/pull/4542))
88
- Use single `LifecycleObserver` and multi-cast it to the integrations interested in lifecycle states ([#4567](https://github.com/getsentry/sentry-java/pull/4567))
9+
- Add `sentry.origin` attribute to logs ([#4618](https://github.com/getsentry/sentry-java/pull/4618))
10+
- This helps identify which integration captured a log event
911
- Prewarm `SentryExecutorService` for better performance at runtime ([#4606](https://github.com/getsentry/sentry-java/pull/4606))
1012

1113
### Fixes
@@ -24,6 +26,8 @@
2426
```
2527
- Fix abstract method error in `SentrySupportSQLiteDatabase` ([#4597](https://github.com/getsentry/sentry-java/pull/4597))
2628
- Ensure frame metrics listeners are registered/unregistered on the main thread ([#4582](https://github.com/getsentry/sentry-java/pull/4582))
29+
- Do not report cached events as lost ([#4575](https://github.com/getsentry/sentry-java/pull/4575))
30+
- Previously events were recorded as lost early despite being retried later through the cache
2731

2832
## 8.18.0
2933

sentry-android-core/api/sentry-android-core.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ public final class io/sentry/android/core/cache/AndroidEnvelopeCache : io/sentry
483483
public static fun hasStartupCrashMarker (Lio/sentry/SentryOptions;)Z
484484
public static fun lastReportedAnr (Lio/sentry/SentryOptions;)Ljava/lang/Long;
485485
public fun store (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V
486+
public fun storeEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Z
486487
}
487488

488489
public class io/sentry/android/core/performance/ActivityLifecycleCallbacksAdapter : android/app/Application$ActivityLifecycleCallbacks {

sentry-android-core/src/main/java/io/sentry/android/core/SentryLogcatAdapter.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import io.sentry.Sentry;
77
import io.sentry.SentryLevel;
88
import io.sentry.SentryLogLevel;
9+
import io.sentry.logger.SentryLogParameters;
910
import org.jetbrains.annotations.ApiStatus;
1011
import org.jetbrains.annotations.NotNull;
1112
import org.jetbrains.annotations.Nullable;
@@ -56,10 +57,13 @@ private static void addAsLog(
5657
return;
5758
}
5859
final @Nullable String trMessage = tr != null ? tr.getMessage() : null;
60+
final @NotNull SentryLogParameters params = new SentryLogParameters();
61+
params.setOrigin("auto.log.logcat");
62+
5963
if (tr == null || trMessage == null) {
60-
scopes.logger().log(level, msg);
64+
scopes.logger().log(level, params, msg);
6165
} else {
62-
scopes.logger().log(level, msg != null ? (msg + "\n" + trMessage) : trMessage);
66+
scopes.logger().log(level, params, msg != null ? (msg + "\n" + trMessage) : trMessage);
6367
}
6468
}
6569

sentry-android-core/src/main/java/io/sentry/android/core/cache/AndroidEnvelopeCache.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,19 @@ public AndroidEnvelopeCache(final @NotNull SentryAndroidOptions options) {
4747
this.currentDateProvider = currentDateProvider;
4848
}
4949

50+
@SuppressWarnings("deprecation")
5051
@Override
5152
public void store(@NotNull SentryEnvelope envelope, @NotNull Hint hint) {
52-
super.store(envelope, hint);
53+
storeInternalAndroid(envelope, hint);
54+
}
55+
56+
@Override
57+
public boolean storeEnvelope(@NotNull SentryEnvelope envelope, @NotNull Hint hint) {
58+
return storeInternalAndroid(envelope, hint);
59+
}
60+
61+
private boolean storeInternalAndroid(@NotNull SentryEnvelope envelope, @NotNull Hint hint) {
62+
final boolean didStore = super.storeEnvelope(envelope, hint);
5363

5464
final SentryAndroidOptions options = (SentryAndroidOptions) this.options;
5565
final TimeSpan sdkInitTimeSpan = AppStartMetrics.getInstance().getSdkInitTimeSpan();
@@ -83,6 +93,7 @@ public void store(@NotNull SentryEnvelope envelope, @NotNull Hint hint) {
8393

8494
writeLastReportedAnrMarker(timestamp);
8595
});
96+
return didStore;
8697
}
8798

8899
@TestOnly

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class SentryLogcatAdapterTest {
6464
SentryLogcatAdapter.v(tag, "$commonMsg verbose")
6565
fixture.breadcrumbs.first().assert(tag, "$commonMsg verbose", SentryLevel.DEBUG)
6666
fixture.logs.first().assert("$commonMsg verbose", SentryLogLevel.TRACE)
67+
assertEquals("auto.log.logcat", fixture.logs.first().attributes?.get("sentry.origin")?.value)
6768
}
6869

6970
@Test

sentry-android-core/src/test/java/io/sentry/android/core/cache/AndroidEnvelopeCacheTest.kt

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package io.sentry.android.core.cache
22

3+
import io.sentry.ISerializer
34
import io.sentry.NoOpLogger
45
import io.sentry.SentryEnvelope
6+
import io.sentry.SentryOptions
57
import io.sentry.UncaughtExceptionHandlerIntegration.UncaughtExceptionHint
68
import io.sentry.android.core.AnrV2Integration.AnrV2Hint
79
import io.sentry.android.core.SentryAndroidOptions
@@ -18,7 +20,9 @@ import kotlin.test.assertFalse
1820
import kotlin.test.assertTrue
1921
import org.junit.Rule
2022
import org.junit.rules.TemporaryFolder
23+
import org.mockito.kotlin.any
2124
import org.mockito.kotlin.mock
25+
import org.mockito.kotlin.same
2226
import org.mockito.kotlin.whenever
2327

2428
class AndroidEnvelopeCacheTest {
@@ -35,8 +39,10 @@ class AndroidEnvelopeCacheTest {
3539
dir: TemporaryFolder,
3640
appStartMillis: Long? = null,
3741
currentTimeMillis: Long? = null,
42+
optionsCallback: ((SentryOptions) -> Unit)? = null,
3843
): AndroidEnvelopeCache {
3944
options.cacheDirPath = dir.newFolder("sentry-cache").absolutePath
45+
optionsCallback?.invoke(options)
4046
val outboxDir = File(options.outboxPath!!)
4147
outboxDir.mkdirs()
4248

@@ -82,7 +88,7 @@ class AndroidEnvelopeCacheTest {
8288
val cache = fixture.getSut(tmpDir)
8389

8490
val hints = HintUtils.createWithTypeCheckHint(UncaughtHint())
85-
cache.store(fixture.envelope, hints)
91+
cache.storeEnvelope(fixture.envelope, hints)
8692

8793
assertFalse(fixture.startupCrashMarkerFile.exists())
8894
}
@@ -92,7 +98,7 @@ class AndroidEnvelopeCacheTest {
9298
val cache = fixture.getSut(dir = tmpDir, appStartMillis = 1000L, currentTimeMillis = 5000L)
9399

94100
val hints = HintUtils.createWithTypeCheckHint(UncaughtHint())
95-
cache.store(fixture.envelope, hints)
101+
cache.storeEnvelope(fixture.envelope, hints)
96102

97103
assertFalse(fixture.startupCrashMarkerFile.exists())
98104
}
@@ -104,7 +110,7 @@ class AndroidEnvelopeCacheTest {
104110
fixture.options.cacheDirPath = null
105111

106112
val hints = HintUtils.createWithTypeCheckHint(UncaughtHint())
107-
cache.store(fixture.envelope, hints)
113+
cache.storeEnvelope(fixture.envelope, hints)
108114

109115
assertFalse(fixture.startupCrashMarkerFile.exists())
110116
}
@@ -114,7 +120,7 @@ class AndroidEnvelopeCacheTest {
114120
val cache = fixture.getSut(dir = tmpDir, appStartMillis = 1000L, currentTimeMillis = 2000L)
115121

116122
val hints = HintUtils.createWithTypeCheckHint(UncaughtHint())
117-
cache.store(fixture.envelope, hints)
123+
cache.storeEnvelope(fixture.envelope, hints)
118124

119125
assertTrue(fixture.startupCrashMarkerFile.exists())
120126
}
@@ -138,7 +144,7 @@ class AndroidEnvelopeCacheTest {
138144
HintUtils.createWithTypeCheckHint(
139145
AnrV2Hint(0, NoOpLogger.getInstance(), 12345678L, false, false)
140146
)
141-
cache.store(fixture.envelope, hints)
147+
cache.storeEnvelope(fixture.envelope, hints)
142148

143149
assertFalse(fixture.lastReportedAnrFile.exists())
144150
}
@@ -151,7 +157,7 @@ class AndroidEnvelopeCacheTest {
151157
HintUtils.createWithTypeCheckHint(
152158
AnrV2Hint(0, NoOpLogger.getInstance(), 12345678L, false, false)
153159
)
154-
cache.store(fixture.envelope, hints)
160+
cache.storeEnvelope(fixture.envelope, hints)
155161

156162
assertTrue(fixture.lastReportedAnrFile.exists())
157163
assertEquals("12345678", fixture.lastReportedAnrFile.readText())
@@ -189,5 +195,17 @@ class AndroidEnvelopeCacheTest {
189195
assertEquals(87654321L, lastReportedAnr)
190196
}
191197

198+
@Test
199+
fun `returns false if storing fails`() {
200+
val serializer = mock<ISerializer>()
201+
val cache = fixture.getSut(tmpDir) { options -> options.setSerializer(serializer) }
202+
whenever(serializer.serialize(same(fixture.envelope), any()))
203+
.thenThrow(RuntimeException("forced ex"))
204+
val hints = HintUtils.createWithTypeCheckHint(UncaughtHint())
205+
206+
val didStore = cache.storeEnvelope(fixture.envelope, hints)
207+
assertFalse(didStore)
208+
}
209+
192210
internal class UncaughtHint : UncaughtExceptionHint(0, NoOpLogger.getInstance())
193211
}

sentry-android-timber/src/main/java/io/sentry/android/timber/SentryTimberTree.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import io.sentry.IScopes
66
import io.sentry.SentryEvent
77
import io.sentry.SentryLevel
88
import io.sentry.SentryLogLevel
9+
import io.sentry.logger.SentryLogParameters
910
import io.sentry.protocol.Message
1011
import timber.log.Timber
1112

@@ -244,12 +245,15 @@ public class SentryTimberTree(
244245
) {
245246
// checks the log level
246247
if (isLoggable(sentryLogLevel, minLogLevel)) {
248+
val params = SentryLogParameters()
249+
params.origin = "auto.log.timber"
250+
247251
val throwableMsg = throwable?.message
248252
when {
249253
msg != null && throwableMsg != null ->
250-
scopes.logger().log(sentryLogLevel, "$msg\n$throwableMsg", *args)
251-
msg != null -> scopes.logger().log(sentryLogLevel, msg, *args)
252-
throwableMsg != null -> scopes.logger().log(sentryLogLevel, throwableMsg, *args)
254+
scopes.logger().log(sentryLogLevel, params, "$msg\n$throwableMsg", *args)
255+
msg != null -> scopes.logger().log(sentryLogLevel, params, msg, *args)
256+
throwableMsg != null -> scopes.logger().log(sentryLogLevel, params, throwableMsg, *args)
253257
}
254258
}
255259
}

sentry-android-timber/src/test/java/io/sentry/android/timber/SentryTimberTreeTest.kt

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.sentry.Scopes
55
import io.sentry.SentryLevel
66
import io.sentry.SentryLogLevel
77
import io.sentry.logger.ILoggerApi
8+
import io.sentry.logger.SentryLogParameters
89
import kotlin.test.BeforeTest
910
import kotlin.test.Test
1011
import kotlin.test.assertEquals
@@ -248,21 +249,28 @@ class SentryTimberTreeTest {
248249
val sut = fixture.getSut()
249250
sut.e("test count: %d %d", 32, 5)
250251

251-
verify(fixture.logs).log(eq(SentryLogLevel.ERROR), eq("test count: %d %d"), eq(32), eq(5))
252+
verify(fixture.logs)
253+
.log(
254+
eq(SentryLogLevel.ERROR),
255+
check<SentryLogParameters> { assertEquals("auto.log.timber", it.origin) },
256+
eq("test count: %d %d"),
257+
eq(32),
258+
eq(5),
259+
)
252260
}
253261

254262
@Test
255263
fun `Tree adds a log if min level is equal`() {
256264
val sut = fixture.getSut()
257265
sut.i(Throwable("test"))
258-
verify(fixture.logs).log(any(), any())
266+
verify(fixture.logs).log(any(), any<SentryLogParameters>(), any<String>())
259267
}
260268

261269
@Test
262270
fun `Tree adds a log if min level is higher`() {
263271
val sut = fixture.getSut()
264272
sut.e(Throwable("test"))
265-
verify(fixture.logs).log(any(), any<String>(), any())
273+
verify(fixture.logs).log(any(), any<SentryLogParameters>(), any<String>(), any())
266274
}
267275

268276
@Test
@@ -277,15 +285,25 @@ class SentryTimberTreeTest {
277285
val sut = fixture.getSut()
278286
sut.i("message")
279287

280-
verify(fixture.logs).log(eq(SentryLogLevel.INFO), eq("message"))
288+
verify(fixture.logs)
289+
.log(
290+
eq(SentryLogLevel.INFO),
291+
check<SentryLogParameters> { assertEquals("auto.log.timber", it.origin) },
292+
eq("message"),
293+
)
281294
}
282295

283296
@Test
284297
fun `Tree adds an error log`() {
285298
val sut = fixture.getSut()
286299
sut.e(Throwable("test"))
287300

288-
verify(fixture.logs).log(eq(SentryLogLevel.ERROR), eq("test"))
301+
verify(fixture.logs)
302+
.log(
303+
eq(SentryLogLevel.ERROR),
304+
check<SentryLogParameters> { assertEquals("auto.log.timber", it.origin) },
305+
eq("test"),
306+
)
289307
}
290308

291309
@Test
@@ -300,14 +318,24 @@ class SentryTimberTreeTest {
300318
val sut = fixture.getSut()
301319
sut.e(Throwable("throwable message"))
302320

303-
verify(fixture.logs).log(eq(SentryLogLevel.ERROR), eq("throwable message"))
321+
verify(fixture.logs)
322+
.log(
323+
eq(SentryLogLevel.ERROR),
324+
check<SentryLogParameters> { assertEquals("auto.log.timber", it.origin) },
325+
eq("throwable message"),
326+
)
304327
}
305328

306329
@Test
307330
fun `Tree logs throwable and message`() {
308331
val sut = fixture.getSut()
309332
sut.e(Throwable("throwable message"), "My message")
310333

311-
verify(fixture.logs).log(eq(SentryLogLevel.ERROR), eq("My message\nthrowable message"))
334+
verify(fixture.logs)
335+
.log(
336+
eq(SentryLogLevel.ERROR),
337+
check<SentryLogParameters> { assertEquals("auto.log.timber", it.origin) },
338+
eq("My message\nthrowable message"),
339+
)
312340
}
313341
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ protected void captureLog(@NotNull LogRecord loggingEvent) {
158158

159159
final @NotNull String formattedMessage = maybeFormatted(arguments, message);
160160
final @NotNull SentryLogParameters params = SentryLogParameters.create(attributes);
161+
params.setOrigin("auto.log.jul");
161162

162163
Sentry.logger().log(sentryLevel, params, formattedMessage, arguments);
163164
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,12 @@ class SentryHandlerTest {
414414
Sentry.flush(1000)
415415

416416
verify(fixture.transport)
417-
.send(checkLogs { event -> assertEquals(SentryLogLevel.TRACE, event.items.first().level) })
417+
.send(
418+
checkLogs { event ->
419+
assertEquals(SentryLogLevel.TRACE, event.items.first().level)
420+
assertEquals("auto.log.jul", event.items.first().attributes?.get("sentry.origin")?.value)
421+
}
422+
)
418423
}
419424

420425
@Test

0 commit comments

Comments
 (0)