Skip to content

Commit 2f2097e

Browse files
authored
Merge branch 'main' into fix/timber-sdk-version
2 parents 9a06be8 + ad99198 commit 2f2097e

22 files changed

+565
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Features
6+
7+
- Collect memory usage in transactions ([#2445](https://github.com/getsentry/sentry-java/pull/2445))
8+
59
### Fixes
610

711
- Don't override sdk name with Timber ([#2450](https://github.com/getsentry/sentry-java/pull/2450))

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public final class io/sentry/android/core/AndroidLogger : io/sentry/ILogger {
3232
public fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
3333
}
3434

35+
public class io/sentry/android/core/AndroidMemoryCollector : io/sentry/IMemoryCollector {
36+
public fun <init> ()V
37+
public fun collect ()Lio/sentry/MemoryCollectionData;
38+
}
39+
3540
public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration, java/io/Closeable {
3641
public fun <init> (Landroid/content/Context;)V
3742
public fun close ()V
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.sentry.android.core;
2+
3+
import android.os.Debug;
4+
import io.sentry.IMemoryCollector;
5+
import io.sentry.MemoryCollectionData;
6+
import org.jetbrains.annotations.ApiStatus;
7+
8+
@ApiStatus.Internal
9+
public class AndroidMemoryCollector implements IMemoryCollector {
10+
@Override
11+
public MemoryCollectionData collect() {
12+
long now = System.currentTimeMillis();
13+
long usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
14+
long usedNativeMemory = Debug.getNativeHeapSize() - Debug.getNativeHeapFreeSize();
15+
return new MemoryCollectionData(now, usedMemory, usedNativeMemory);
16+
}
17+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ static void initializeIntegrationsAndProcessors(
161161
options.setGestureTargetLocators(gestureTargetLocators);
162162
}
163163
options.setMainThreadChecker(AndroidMainThreadChecker.getInstance());
164+
options.setMemoryCollector(new AndroidMemoryCollector());
164165
}
165166

166167
private static void installDefaultIntegrations(
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.sentry.android.core
2+
3+
import android.os.Debug
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
import kotlin.test.assertNotEquals
7+
import kotlin.test.assertNotNull
8+
9+
class AndroidMemoryCollectorTest {
10+
11+
private val fixture = Fixture()
12+
13+
private class Fixture {
14+
val runtime: Runtime = Runtime.getRuntime()
15+
val collector = AndroidMemoryCollector()
16+
}
17+
18+
@Test
19+
fun `when collect, both native and heap memory are collected`() {
20+
val usedNativeMemory = Debug.getNativeHeapSize() - Debug.getNativeHeapFreeSize()
21+
val usedMemory = fixture.runtime.totalMemory() - fixture.runtime.freeMemory()
22+
val data = fixture.collector.collect()
23+
assertNotNull(data)
24+
assertNotEquals(-1, data.usedNativeMemory)
25+
assertEquals(usedNativeMemory, data.usedNativeMemory)
26+
assertEquals(usedMemory, data.usedHeapMemory)
27+
assertNotEquals(0, data.timestamp)
28+
}
29+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,4 +484,11 @@ class AndroidOptionsInitializerTest {
484484
assertTrue { fixture.sentryOptions.gestureTargetLocators[0] is AndroidViewGestureTargetLocator }
485485
assertTrue { fixture.sentryOptions.gestureTargetLocators[1] is ComposeGestureTargetLocator }
486486
}
487+
488+
@Test
489+
fun `AndroidMemoryCollector is set to options`() {
490+
fixture.initSut()
491+
492+
assertTrue { fixture.sentryOptions.memoryCollector is AndroidMemoryCollector }
493+
}
487494
}

sentry/api/sentry.api

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,10 @@ public abstract interface class io/sentry/ILogger {
441441
public abstract fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
442442
}
443443

444+
public abstract interface class io/sentry/IMemoryCollector {
445+
public abstract fun collect ()Lio/sentry/MemoryCollectionData;
446+
}
447+
444448
public abstract interface class io/sentry/IScopeObserver {
445449
public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;)V
446450
public abstract fun removeExtra (Ljava/lang/String;)V
@@ -560,6 +564,11 @@ public final class io/sentry/IpAddressUtils {
560564
public static fun isDefault (Ljava/lang/String;)Z
561565
}
562566

567+
public final class io/sentry/JavaMemoryCollector : io/sentry/IMemoryCollector {
568+
public fun <init> ()V
569+
public fun collect ()Lio/sentry/MemoryCollectionData;
570+
}
571+
563572
public abstract interface class io/sentry/JsonDeserializer {
564573
public abstract fun deserialize (Lio/sentry/JsonObjectReader;Lio/sentry/ILogger;)Ljava/lang/Object;
565574
}
@@ -681,6 +690,14 @@ public final class io/sentry/MeasurementUnit$Information : java/lang/Enum, io/se
681690
public static fun values ()[Lio/sentry/MeasurementUnit$Information;
682691
}
683692

693+
public final class io/sentry/MemoryCollectionData {
694+
public fun <init> (JJ)V
695+
public fun <init> (JJJ)V
696+
public fun getTimestamp ()J
697+
public fun getUsedHeapMemory ()J
698+
public fun getUsedNativeMemory ()J
699+
}
700+
684701
public final class io/sentry/NoOpEnvelopeReader : io/sentry/IEnvelopeReader {
685702
public static fun getInstance ()Lio/sentry/NoOpEnvelopeReader;
686703
public fun read (Ljava/io/InputStream;)Lio/sentry/SentryEnvelope;
@@ -738,6 +755,11 @@ public final class io/sentry/NoOpLogger : io/sentry/ILogger {
738755
public fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
739756
}
740757

758+
public final class io/sentry/NoOpMemoryCollector : io/sentry/IMemoryCollector {
759+
public fun collect ()Lio/sentry/MemoryCollectionData;
760+
public static fun getInstance ()Lio/sentry/NoOpMemoryCollector;
761+
}
762+
741763
public final class io/sentry/NoOpSpan : io/sentry/ISpan {
742764
public fun finish ()V
743765
public fun finish (Lio/sentry/SpanStatus;)V
@@ -1413,6 +1435,7 @@ public class io/sentry/SentryOptions {
14131435
public fun getMaxRequestBodySize ()Lio/sentry/SentryOptions$RequestSize;
14141436
public fun getMaxSpans ()I
14151437
public fun getMaxTraceFileSize ()J
1438+
public fun getMemoryCollector ()Lio/sentry/IMemoryCollector;
14161439
public fun getModulesLoader ()Lio/sentry/internal/modules/IModulesLoader;
14171440
public fun getOutboxPath ()Ljava/lang/String;
14181441
public fun getProfilesSampleRate ()Ljava/lang/Double;
@@ -1500,6 +1523,7 @@ public class io/sentry/SentryOptions {
15001523
public fun setMaxRequestBodySize (Lio/sentry/SentryOptions$RequestSize;)V
15011524
public fun setMaxSpans (I)V
15021525
public fun setMaxTraceFileSize (J)V
1526+
public fun setMemoryCollector (Lio/sentry/IMemoryCollector;)V
15031527
public fun setModulesLoader (Lio/sentry/internal/modules/IModulesLoader;)V
15041528
public fun setPrintUncaughtStackTrace (Z)V
15051529
public fun setProfilesSampleRate (Ljava/lang/Double;)V
@@ -1946,6 +1970,12 @@ public final class io/sentry/TransactionOptions {
19461970
public fun setWaitForChildren (Z)V
19471971
}
19481972

1973+
public final class io/sentry/TransactionPerformanceCollector {
1974+
public fun <init> (Lio/sentry/SentryOptions;)V
1975+
public fun start (Lio/sentry/ITransaction;)V
1976+
public fun stop (Lio/sentry/ITransaction;)Ljava/util/List;
1977+
}
1978+
19491979
public final class io/sentry/TypeCheckHint {
19501980
public static final field ANDROID_ACTIVITY Ljava/lang/String;
19511981
public static final field ANDROID_CONFIGURATION Ljava/lang/String;

sentry/src/main/java/io/sentry/Hub.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public final class Hub implements IHub {
3030
private final @NotNull TracesSampler tracesSampler;
3131
private final @NotNull Map<Throwable, Pair<WeakReference<ISpan>, String>> throwableToSpan =
3232
Collections.synchronizedMap(new WeakHashMap<>());
33+
private final @NotNull TransactionPerformanceCollector transactionPerformanceCollector;
3334

3435
public Hub(final @NotNull SentryOptions options) {
3536
this(options, createRootStackItem(options));
@@ -44,6 +45,7 @@ private Hub(final @NotNull SentryOptions options, final @NotNull Stack stack) {
4445
this.tracesSampler = new TracesSampler(options);
4546
this.stack = stack;
4647
this.lastEventId = SentryId.EMPTY_ID;
48+
this.transactionPerformanceCollector = new TransactionPerformanceCollector(options);
4749

4850
// Integrations will use this Hub instance once registered.
4951
// Make sure Hub ready to be used then.
@@ -730,7 +732,8 @@ public void flush(long timeoutMillis) {
730732
waitForChildren,
731733
idleTimeout,
732734
trimEnd,
733-
transactionFinishedCallback);
735+
transactionFinishedCallback,
736+
transactionPerformanceCollector);
734737

735738
// The listener is called only if the transaction exists, as the transaction is needed to
736739
// stop it
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.sentry;
2+
3+
import org.jetbrains.annotations.ApiStatus;
4+
import org.jetbrains.annotations.Nullable;
5+
6+
/** Used for collecting data about memory load when a transaction is active. */
7+
@ApiStatus.Internal
8+
public interface IMemoryCollector {
9+
/** Used for collecting data about memory load when a transaction is active. */
10+
@Nullable
11+
MemoryCollectionData collect();
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.sentry;
2+
3+
import org.jetbrains.annotations.ApiStatus;
4+
import org.jetbrains.annotations.NotNull;
5+
import org.jetbrains.annotations.Nullable;
6+
7+
@ApiStatus.Internal
8+
public final class JavaMemoryCollector implements IMemoryCollector {
9+
10+
private final @NotNull Runtime runtime = Runtime.getRuntime();
11+
12+
@Override
13+
public @Nullable MemoryCollectionData collect() {
14+
final long now = System.currentTimeMillis();
15+
final long usedMemory = runtime.totalMemory() - runtime.freeMemory();
16+
return new MemoryCollectionData(now, usedMemory);
17+
}
18+
}

0 commit comments

Comments
 (0)