From 4d1f5099c15a3a7e51b0a0fdb2e2252a3e532c9c Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Wed, 13 Sep 2023 13:18:42 +0200 Subject: [PATCH 1/3] Always send memory stats for transactions --- .../sentry/android/core/DeviceInfoUtil.java | 28 +++++++++---------- .../sentry/android/core/DeviceInfoUtilTest.kt | 13 --------- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java b/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java index d74a8b1e2d..9d23d264b0 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java @@ -132,9 +132,20 @@ public Device collectDeviceInformation( device.setProcessorCount(cpuFrequencies.size()); } + final @Nullable ActivityManager.MemoryInfo memInfo = + ContextUtils.getMemInfo(context, options.getLogger()); + if (memInfo != null) { + // in bytes + device.setMemorySize(getMemorySize(memInfo)); + if (collectDynamicData) { + device.setFreeMemory(memInfo.availMem); + device.setLowMemory(memInfo.lowMemory); + } + } + // setting such values require IO hence we don't run for transactions if (collectDeviceIO && options.isCollectAdditionalContext()) { - setDeviceIO(device, collectDynamicData); + setDeviceIO(device); } return device; @@ -171,7 +182,7 @@ public ContextUtils.SideLoadedInfo getSideLoadedInfo() { return sideLoadedInfo; } - private void setDeviceIO(final @NotNull Device device, final boolean includeDynamicData) { + private void setDeviceIO(final @NotNull Device device) { final Intent batteryIntent = getBatteryIntent(); if (batteryIntent != null) { device.setBatteryLevel(getBatteryLevel(batteryIntent)); @@ -192,19 +203,6 @@ private void setDeviceIO(final @NotNull Device device, final boolean includeDyna } device.setOnline(connected); - final @Nullable ActivityManager.MemoryInfo memInfo = - ContextUtils.getMemInfo(context, options.getLogger()); - if (memInfo != null) { - // in bytes - device.setMemorySize(getMemorySize(memInfo)); - if (includeDynamicData) { - device.setFreeMemory(memInfo.availMem); - device.setLowMemory(memInfo.lowMemory); - } - // there are runtime.totalMemory() and runtime.freeMemory(), but I kept the same for - // compatibility - } - // this way of getting the size of storage might be problematic for storages bigger than 2GB // check the use of // https://developer.android.com/reference/java/io/File.html#getFreeSpace%28%29 diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt index 5c90395e3b..2854383dce 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt @@ -98,19 +98,6 @@ class DeviceInfoUtilTest { assertNotNull(deviceInfo.freeStorage) } - @Test - fun `does not include device io data when disabled`() { - val options = SentryAndroidOptions().apply { - isCollectAdditionalContext = true - } - val deviceInfoUtil = DeviceInfoUtil.getInstance(context, options) - val deviceInfo = deviceInfoUtil.collectDeviceInformation(false, false) - - assertNull(deviceInfo.memorySize) - assertNull(deviceInfo.storageSize) - assertNull(deviceInfo.freeStorage) - } - @Test fun `does include dynamic data when enabled`() { val options = SentryAndroidOptions().apply { From 6240f81b6947c9416932837834447847acadea55 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Wed, 13 Sep 2023 13:27:54 +0200 Subject: [PATCH 2/3] Changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a5c523ed..71cae8b0f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ - Add `sendModules` option for disable sending modules ([#2926](https://github.com/getsentry/sentry-java/pull/2926)) - Send `db.system` and `db.name` in span data for androidx.sqlite spans ([#2928](https://github.com/getsentry/sentry-java/pull/2928)) +### Fixes + +- Always send memory stats for transactions ([#2936](https://github.com/getsentry/sentry-java/pull/2936)) + - This makes it possible to query transactions by the `device.class` tag on Sentry + ### Dependencies - Bump Gradle from v8.2.1 to v8.3.0 ([#2900](https://github.com/getsentry/sentry-java/pull/2900)) From da4c1b26749f38bdea33a5b4ee6b96bf43168ca1 Mon Sep 17 00:00:00 2001 From: Roman Zavarnitsyn Date: Wed, 13 Sep 2023 14:43:31 +0200 Subject: [PATCH 3/3] Cache total memory on init and reuse later --- .../sentry/android/core/DeviceInfoUtil.java | 32 ++++++++++++------- .../sentry/android/core/DeviceInfoUtilTest.kt | 15 ++++++++- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java b/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java index 9d23d264b0..304a30116a 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/DeviceInfoUtil.java @@ -47,6 +47,8 @@ public final class DeviceInfoUtil { private final @Nullable ContextUtils.SideLoadedInfo sideLoadedInfo; private final @NotNull OperatingSystem os; + private final @Nullable Long totalMem; + public DeviceInfoUtil( final @NotNull Context context, final @NotNull SentryAndroidOptions options) { this.context = context; @@ -59,6 +61,13 @@ public DeviceInfoUtil( isEmulator = buildInfoProvider.isEmulator(); sideLoadedInfo = ContextUtils.retrieveSideLoadedInfo(context, options.getLogger(), buildInfoProvider); + final @Nullable ActivityManager.MemoryInfo memInfo = + ContextUtils.getMemInfo(context, options.getLogger()); + if (memInfo != null) { + totalMem = getMemorySize(memInfo); + } else { + totalMem = null; + } } @NotNull @@ -132,20 +141,11 @@ public Device collectDeviceInformation( device.setProcessorCount(cpuFrequencies.size()); } - final @Nullable ActivityManager.MemoryInfo memInfo = - ContextUtils.getMemInfo(context, options.getLogger()); - if (memInfo != null) { - // in bytes - device.setMemorySize(getMemorySize(memInfo)); - if (collectDynamicData) { - device.setFreeMemory(memInfo.availMem); - device.setLowMemory(memInfo.lowMemory); - } - } + device.setMemorySize(totalMem); // setting such values require IO hence we don't run for transactions if (collectDeviceIO && options.isCollectAdditionalContext()) { - setDeviceIO(device); + setDeviceIO(device, collectDynamicData); } return device; @@ -182,7 +182,7 @@ public ContextUtils.SideLoadedInfo getSideLoadedInfo() { return sideLoadedInfo; } - private void setDeviceIO(final @NotNull Device device) { + private void setDeviceIO(final @NotNull Device device, final boolean includeDynamicData) { final Intent batteryIntent = getBatteryIntent(); if (batteryIntent != null) { device.setBatteryLevel(getBatteryLevel(batteryIntent)); @@ -203,6 +203,14 @@ private void setDeviceIO(final @NotNull Device device) { } device.setOnline(connected); + final @Nullable ActivityManager.MemoryInfo memInfo = + ContextUtils.getMemInfo(context, options.getLogger()); + if (memInfo != null && includeDynamicData) { + // in bytes + device.setFreeMemory(memInfo.availMem); + device.setLowMemory(memInfo.lowMemory); + } + // this way of getting the size of storage might be problematic for storages bigger than 2GB // check the use of // https://developer.android.com/reference/java/io/File.html#getFreeSpace%28%29 diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt index 2854383dce..c01da4b6e7 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/DeviceInfoUtilTest.kt @@ -34,7 +34,7 @@ class DeviceInfoUtilTest { } @Test - fun `provides os and sideloaded info`() { + fun `provides os, memory and sideloaded info`() { val deviceInfoUtil = DeviceInfoUtil.getInstance(context, SentryAndroidOptions()) val os = deviceInfoUtil.operatingSystem @@ -48,6 +48,7 @@ class DeviceInfoUtilTest { assertNotNull(sideLoadedInfo.isSideLoaded) assertNotNull(deviceInfo.isSimulator) + assertNotNull(deviceInfo.memorySize) } @Test @@ -98,6 +99,18 @@ class DeviceInfoUtilTest { assertNotNull(deviceInfo.freeStorage) } + @Test + fun `does not include device io data when disabled`() { + val options = SentryAndroidOptions().apply { + isCollectAdditionalContext = true + } + val deviceInfoUtil = DeviceInfoUtil.getInstance(context, options) + val deviceInfo = deviceInfoUtil.collectDeviceInformation(false, false) + + assertNull(deviceInfo.storageSize) + assertNull(deviceInfo.freeStorage) + } + @Test fun `does include dynamic data when enabled`() { val options = SentryAndroidOptions().apply {