Skip to content

Commit

Permalink
Merge branch 'main' into fix/timber-sdk-version
Browse files Browse the repository at this point in the history
  • Loading branch information
romtsn authored Jan 3, 2023
2 parents 9a06be8 + ad99198 commit 2f2097e
Show file tree
Hide file tree
Showing 22 changed files with 565 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Features

- Collect memory usage in transactions ([#2445](https://github.com/getsentry/sentry-java/pull/2445))

### Fixes

- Don't override sdk name with Timber ([#2450](https://github.com/getsentry/sentry-java/pull/2450))
Expand Down
5 changes: 5 additions & 0 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ public final class io/sentry/android/core/AndroidLogger : io/sentry/ILogger {
public fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
}

public class io/sentry/android/core/AndroidMemoryCollector : io/sentry/IMemoryCollector {
public fun <init> ()V
public fun collect ()Lio/sentry/MemoryCollectionData;
}

public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;)V
public fun close ()V
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.sentry.android.core;

import android.os.Debug;
import io.sentry.IMemoryCollector;
import io.sentry.MemoryCollectionData;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public class AndroidMemoryCollector implements IMemoryCollector {
@Override
public MemoryCollectionData collect() {
long now = System.currentTimeMillis();
long usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
long usedNativeMemory = Debug.getNativeHeapSize() - Debug.getNativeHeapFreeSize();
return new MemoryCollectionData(now, usedMemory, usedNativeMemory);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ static void initializeIntegrationsAndProcessors(
options.setGestureTargetLocators(gestureTargetLocators);
}
options.setMainThreadChecker(AndroidMainThreadChecker.getInstance());
options.setMemoryCollector(new AndroidMemoryCollector());
}

private static void installDefaultIntegrations(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.sentry.android.core

import android.os.Debug
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.assertNotNull

class AndroidMemoryCollectorTest {

private val fixture = Fixture()

private class Fixture {
val runtime: Runtime = Runtime.getRuntime()
val collector = AndroidMemoryCollector()
}

@Test
fun `when collect, both native and heap memory are collected`() {
val usedNativeMemory = Debug.getNativeHeapSize() - Debug.getNativeHeapFreeSize()
val usedMemory = fixture.runtime.totalMemory() - fixture.runtime.freeMemory()
val data = fixture.collector.collect()
assertNotNull(data)
assertNotEquals(-1, data.usedNativeMemory)
assertEquals(usedNativeMemory, data.usedNativeMemory)
assertEquals(usedMemory, data.usedHeapMemory)
assertNotEquals(0, data.timestamp)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -484,4 +484,11 @@ class AndroidOptionsInitializerTest {
assertTrue { fixture.sentryOptions.gestureTargetLocators[0] is AndroidViewGestureTargetLocator }
assertTrue { fixture.sentryOptions.gestureTargetLocators[1] is ComposeGestureTargetLocator }
}

@Test
fun `AndroidMemoryCollector is set to options`() {
fixture.initSut()

assertTrue { fixture.sentryOptions.memoryCollector is AndroidMemoryCollector }
}
}
30 changes: 30 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,10 @@ public abstract interface class io/sentry/ILogger {
public abstract fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
}

public abstract interface class io/sentry/IMemoryCollector {
public abstract fun collect ()Lio/sentry/MemoryCollectionData;
}

public abstract interface class io/sentry/IScopeObserver {
public abstract fun addBreadcrumb (Lio/sentry/Breadcrumb;)V
public abstract fun removeExtra (Ljava/lang/String;)V
Expand Down Expand Up @@ -560,6 +564,11 @@ public final class io/sentry/IpAddressUtils {
public static fun isDefault (Ljava/lang/String;)Z
}

public final class io/sentry/JavaMemoryCollector : io/sentry/IMemoryCollector {
public fun <init> ()V
public fun collect ()Lio/sentry/MemoryCollectionData;
}

public abstract interface class io/sentry/JsonDeserializer {
public abstract fun deserialize (Lio/sentry/JsonObjectReader;Lio/sentry/ILogger;)Ljava/lang/Object;
}
Expand Down Expand Up @@ -681,6 +690,14 @@ public final class io/sentry/MeasurementUnit$Information : java/lang/Enum, io/se
public static fun values ()[Lio/sentry/MeasurementUnit$Information;
}

public final class io/sentry/MemoryCollectionData {
public fun <init> (JJ)V
public fun <init> (JJJ)V
public fun getTimestamp ()J
public fun getUsedHeapMemory ()J
public fun getUsedNativeMemory ()J
}

public final class io/sentry/NoOpEnvelopeReader : io/sentry/IEnvelopeReader {
public static fun getInstance ()Lio/sentry/NoOpEnvelopeReader;
public fun read (Ljava/io/InputStream;)Lio/sentry/SentryEnvelope;
Expand Down Expand Up @@ -738,6 +755,11 @@ public final class io/sentry/NoOpLogger : io/sentry/ILogger {
public fun log (Lio/sentry/SentryLevel;Ljava/lang/Throwable;Ljava/lang/String;[Ljava/lang/Object;)V
}

public final class io/sentry/NoOpMemoryCollector : io/sentry/IMemoryCollector {
public fun collect ()Lio/sentry/MemoryCollectionData;
public static fun getInstance ()Lio/sentry/NoOpMemoryCollector;
}

public final class io/sentry/NoOpSpan : io/sentry/ISpan {
public fun finish ()V
public fun finish (Lio/sentry/SpanStatus;)V
Expand Down Expand Up @@ -1413,6 +1435,7 @@ public class io/sentry/SentryOptions {
public fun getMaxRequestBodySize ()Lio/sentry/SentryOptions$RequestSize;
public fun getMaxSpans ()I
public fun getMaxTraceFileSize ()J
public fun getMemoryCollector ()Lio/sentry/IMemoryCollector;
public fun getModulesLoader ()Lio/sentry/internal/modules/IModulesLoader;
public fun getOutboxPath ()Ljava/lang/String;
public fun getProfilesSampleRate ()Ljava/lang/Double;
Expand Down Expand Up @@ -1500,6 +1523,7 @@ public class io/sentry/SentryOptions {
public fun setMaxRequestBodySize (Lio/sentry/SentryOptions$RequestSize;)V
public fun setMaxSpans (I)V
public fun setMaxTraceFileSize (J)V
public fun setMemoryCollector (Lio/sentry/IMemoryCollector;)V
public fun setModulesLoader (Lio/sentry/internal/modules/IModulesLoader;)V
public fun setPrintUncaughtStackTrace (Z)V
public fun setProfilesSampleRate (Ljava/lang/Double;)V
Expand Down Expand Up @@ -1946,6 +1970,12 @@ public final class io/sentry/TransactionOptions {
public fun setWaitForChildren (Z)V
}

public final class io/sentry/TransactionPerformanceCollector {
public fun <init> (Lio/sentry/SentryOptions;)V
public fun start (Lio/sentry/ITransaction;)V
public fun stop (Lio/sentry/ITransaction;)Ljava/util/List;
}

public final class io/sentry/TypeCheckHint {
public static final field ANDROID_ACTIVITY Ljava/lang/String;
public static final field ANDROID_CONFIGURATION Ljava/lang/String;
Expand Down
5 changes: 4 additions & 1 deletion sentry/src/main/java/io/sentry/Hub.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public final class Hub implements IHub {
private final @NotNull TracesSampler tracesSampler;
private final @NotNull Map<Throwable, Pair<WeakReference<ISpan>, String>> throwableToSpan =
Collections.synchronizedMap(new WeakHashMap<>());
private final @NotNull TransactionPerformanceCollector transactionPerformanceCollector;

public Hub(final @NotNull SentryOptions options) {
this(options, createRootStackItem(options));
Expand All @@ -44,6 +45,7 @@ private Hub(final @NotNull SentryOptions options, final @NotNull Stack stack) {
this.tracesSampler = new TracesSampler(options);
this.stack = stack;
this.lastEventId = SentryId.EMPTY_ID;
this.transactionPerformanceCollector = new TransactionPerformanceCollector(options);

// Integrations will use this Hub instance once registered.
// Make sure Hub ready to be used then.
Expand Down Expand Up @@ -730,7 +732,8 @@ public void flush(long timeoutMillis) {
waitForChildren,
idleTimeout,
trimEnd,
transactionFinishedCallback);
transactionFinishedCallback,
transactionPerformanceCollector);

// The listener is called only if the transaction exists, as the transaction is needed to
// stop it
Expand Down
12 changes: 12 additions & 0 deletions sentry/src/main/java/io/sentry/IMemoryCollector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.sentry;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

/** Used for collecting data about memory load when a transaction is active. */
@ApiStatus.Internal
public interface IMemoryCollector {
/** Used for collecting data about memory load when a transaction is active. */
@Nullable
MemoryCollectionData collect();
}
18 changes: 18 additions & 0 deletions sentry/src/main/java/io/sentry/JavaMemoryCollector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.sentry;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@ApiStatus.Internal
public final class JavaMemoryCollector implements IMemoryCollector {

private final @NotNull Runtime runtime = Runtime.getRuntime();

@Override
public @Nullable MemoryCollectionData collect() {
final long now = System.currentTimeMillis();
final long usedMemory = runtime.totalMemory() - runtime.freeMemory();
return new MemoryCollectionData(now, usedMemory);
}
}
33 changes: 33 additions & 0 deletions sentry/src/main/java/io/sentry/MemoryCollectionData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.sentry;

import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
public final class MemoryCollectionData {
final long timestamp;
final long usedHeapMemory;
final long usedNativeMemory;

public MemoryCollectionData(
final long timestamp, final long usedHeapMemory, final long usedNativeMemory) {
this.timestamp = timestamp;
this.usedHeapMemory = usedHeapMemory;
this.usedNativeMemory = usedNativeMemory;
}

public MemoryCollectionData(final long timestamp, final long usedHeapMemory) {
this(timestamp, usedHeapMemory, -1);
}

public long getTimestamp() {
return timestamp;
}

public long getUsedHeapMemory() {
return usedHeapMemory;
}

public long getUsedNativeMemory() {
return usedNativeMemory;
}
}
21 changes: 21 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpMemoryCollector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.sentry;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

@ApiStatus.Internal
public final class NoOpMemoryCollector implements IMemoryCollector {

private static final NoOpMemoryCollector instance = new NoOpMemoryCollector();

public static NoOpMemoryCollector getInstance() {
return instance;
}

private NoOpMemoryCollector() {}

@Override
public @Nullable MemoryCollectionData collect() {
return null;
}
}
4 changes: 4 additions & 0 deletions sentry/src/main/java/io/sentry/Sentry.java
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ private static boolean initConfigurations(final @NotNull SentryOptions options)
options.setMainThreadChecker(MainThreadChecker.getInstance());
}

if (options.getMemoryCollector() instanceof NoOpMemoryCollector) {
options.setMemoryCollector(new JavaMemoryCollector());
}

return true;
}

Expand Down
23 changes: 23 additions & 0 deletions sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,8 @@ public class SentryOptions {

private @NotNull IMainThreadChecker mainThreadChecker = NoOpMainThreadChecker.getInstance();

private @NotNull IMemoryCollector memoryCollector = NoOpMemoryCollector.getInstance();

/**
* Adds an event processor
*
Expand Down Expand Up @@ -1876,6 +1878,27 @@ public void setMainThreadChecker(final @NotNull IMainThreadChecker mainThreadChe
this.mainThreadChecker = mainThreadChecker;
}

/**
* Gets the memory collector used to collect memory usage during while transaction runs.
*
* @return the memory collector.
*/
@ApiStatus.Internal
public @NotNull IMemoryCollector getMemoryCollector() {
return memoryCollector;
}

/**
* Sets the memory collector to collect memory usage during while transaction runs.
*
* @param memoryCollector - the memory collector. If null, a no op collector will be set.
*/
@ApiStatus.Internal
public void setMemoryCollector(final @Nullable IMemoryCollector memoryCollector) {
this.memoryCollector =
memoryCollector != null ? memoryCollector : NoOpMemoryCollector.getInstance();
}

/** The BeforeSend callback */
public interface BeforeSendCallback {

Expand Down
Loading

0 comments on commit 2f2097e

Please sign in to comment.