diff --git a/CHANGELOG.md b/CHANGELOG.md index 92d7d2ef4b..ba0e84d5d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixes +- Avoid collecting normal frames ([#3782](https://github.com/getsentry/sentry-java/pull/3782)) - Ensure android initialization process continues even if options configuration block throws an exception ([#3887](https://github.com/getsentry/sentry-java/pull/3887)) - Do not report parsing ANR error when there are no threads ([#3888](https://github.com/getsentry/sentry-java/pull/3888)) - This should significantly reduce the number of events with message "Sentry Android SDK failed to parse system thread dump..." reported diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryFrameMetrics.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryFrameMetrics.java index 23409eadea..cf2241757c 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryFrameMetrics.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryFrameMetrics.java @@ -6,7 +6,6 @@ @ApiStatus.Internal final class SentryFrameMetrics { - private int normalFrameCount; private int slowFrameCount; private int frozenFrameCount; @@ -18,15 +17,11 @@ final class SentryFrameMetrics { public SentryFrameMetrics() {} public SentryFrameMetrics( - final int normalFrameCount, final int slowFrameCount, final long slowFrameDelayNanos, final int frozenFrameCount, final long frozenFrameDelayNanos, final long totalDurationNanos) { - - this.normalFrameCount = normalFrameCount; - this.slowFrameCount = slowFrameCount; this.slowFrameDelayNanos = slowFrameDelayNanos; @@ -47,15 +42,9 @@ public void addFrame( } else if (isSlow) { slowFrameDelayNanos += delayNanos; slowFrameCount += 1; - } else { - normalFrameCount += 1; } } - public int getNormalFrameCount() { - return normalFrameCount; - } - public int getSlowFrameCount() { return slowFrameCount; } @@ -72,8 +61,9 @@ public long getFrozenFrameDelayNanos() { return frozenFrameDelayNanos; } - public int getTotalFrameCount() { - return normalFrameCount + slowFrameCount + frozenFrameCount; + /** Returns the sum of the slow and frozen frames. */ + public int getSlowFrozenFrameCount() { + return slowFrameCount + frozenFrameCount; } public long getTotalDurationNanos() { @@ -81,8 +71,6 @@ public long getTotalDurationNanos() { } public void clear() { - normalFrameCount = 0; - slowFrameCount = 0; slowFrameDelayNanos = 0; @@ -95,7 +83,6 @@ public void clear() { @NotNull public SentryFrameMetrics duplicate() { return new SentryFrameMetrics( - normalFrameCount, slowFrameCount, slowFrameDelayNanos, frozenFrameCount, @@ -110,7 +97,6 @@ public SentryFrameMetrics duplicate() { @NotNull public SentryFrameMetrics diffTo(final @NotNull SentryFrameMetrics other) { return new SentryFrameMetrics( - normalFrameCount - other.normalFrameCount, slowFrameCount - other.slowFrameCount, slowFrameDelayNanos - other.slowFrameDelayNanos, frozenFrameCount - other.frozenFrameCount, @@ -123,8 +109,7 @@ public SentryFrameMetrics diffTo(final @NotNull SentryFrameMetrics other) { * to 0 */ public boolean containsValidData() { - return normalFrameCount >= 0 - && slowFrameCount >= 0 + return slowFrameCount >= 0 && slowFrameDelayNanos >= 0 && frozenFrameCount >= 0 && frozenFrameDelayNanos >= 0 diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SpanFrameMetricsCollector.java b/sentry-android-core/src/main/java/io/sentry/android/core/SpanFrameMetricsCollector.java index 5535bccb91..b4279db13f 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SpanFrameMetricsCollector.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SpanFrameMetricsCollector.java @@ -192,7 +192,7 @@ private void captureFrameMetrics(@NotNull final ISpan span) { } } - int totalFrameCount = frameMetrics.getTotalFrameCount(); + int totalFrameCount = frameMetrics.getSlowFrozenFrameCount(); final long nextScheduledFrameNanos = frameMetricsCollector.getLastKnownFrameStartTimeNanos(); // nextScheduledFrameNanos might be -1 if no frames have been scheduled for drawing yet @@ -254,15 +254,17 @@ public void onFrameMetricCollected( (long) ((double) ONE_SECOND_NANOS / (double) refreshRate); lastKnownFrameDurationNanos = expectedFrameDurationNanos; - frames.add( - new Frame( - frameStartNanos, - frameEndNanos, - durationNanos, - delayNanos, - isSlow, - isFrozen, - expectedFrameDurationNanos)); + if (isSlow || isFrozen) { + frames.add( + new Frame( + frameStartNanos, + frameEndNanos, + durationNanos, + delayNanos, + isSlow, + isFrozen, + expectedFrameDurationNanos)); + } } private static int interpolateFrameCount( @@ -277,7 +279,7 @@ private static int interpolateFrameCount( final long frameMetricsDurationNanos = frameMetrics.getTotalDurationNanos(); final long nonRenderedDuration = spanDurationNanos - frameMetricsDurationNanos; if (nonRenderedDuration > 0) { - return (int) (nonRenderedDuration / frameDurationNanos); + return (int) Math.ceil((double) nonRenderedDuration / frameDurationNanos); } return 0; } diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SentryFrameMetricsTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SentryFrameMetricsTest.kt index 1e992041b0..a8138b61ff 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SentryFrameMetricsTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SentryFrameMetricsTest.kt @@ -6,15 +6,6 @@ import kotlin.test.assertFalse import kotlin.test.assertTrue class SentryFrameMetricsTest { - @Test - fun addFastFrame() { - val frameMetrics = SentryFrameMetrics() - frameMetrics.addFrame(10, 0, false, false) - assertEquals(1, frameMetrics.normalFrameCount) - - frameMetrics.addFrame(10, 0, false, false) - assertEquals(2, frameMetrics.normalFrameCount) - } @Test fun addSlowFrame() { @@ -43,10 +34,12 @@ class SentryFrameMetricsTest { @Test fun totalFrameCount() { val frameMetrics = SentryFrameMetrics() + // Normal frames are ignored frameMetrics.addFrame(10, 0, false, false) + // Slow and frozen frames are considered frameMetrics.addFrame(116, 100, true, false) frameMetrics.addFrame(1016, 1000, true, true) - assertEquals(3, frameMetrics.totalFrameCount) + assertEquals(2, frameMetrics.slowFrozenFrameCount) } @Test @@ -57,12 +50,11 @@ class SentryFrameMetricsTest { frameMetrics.addFrame(1016, 1000, true, true) val dup = frameMetrics.duplicate() - assertEquals(1, dup.normalFrameCount) assertEquals(1, dup.slowFrameCount) assertEquals(100, dup.slowFrameDelayNanos) assertEquals(1, dup.frozenFrameCount) assertEquals(1000, dup.frozenFrameDelayNanos) - assertEquals(3, dup.totalFrameCount) + assertEquals(2, dup.slowFrozenFrameCount) } @Test @@ -89,7 +81,7 @@ class SentryFrameMetricsTest { assertEquals(1, diff.frozenFrameCount) assertEquals(1000, diff.frozenFrameDelayNanos) - assertEquals(2, diff.totalFrameCount) + assertEquals(2, diff.slowFrozenFrameCount) } @Test @@ -102,12 +94,11 @@ class SentryFrameMetricsTest { frameMetrics.clear() - assertEquals(0, frameMetrics.normalFrameCount) assertEquals(0, frameMetrics.slowFrameCount) assertEquals(0, frameMetrics.slowFrameDelayNanos) assertEquals(0, frameMetrics.frozenFrameCount) assertEquals(0, frameMetrics.frozenFrameDelayNanos) - assertEquals(0, frameMetrics.totalFrameCount) + assertEquals(0, frameMetrics.slowFrozenFrameCount) } @Test diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/SpanFrameMetricsCollectorTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/SpanFrameMetricsCollectorTest.kt index d8ff8fde2e..0527baf284 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/SpanFrameMetricsCollectorTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/SpanFrameMetricsCollectorTest.kt @@ -192,7 +192,7 @@ class SpanFrameMetricsCollectorTest { sut.onFrameMetricCollected(0, 10, 10, 0, false, false, 60.0f) sut.onFrameMetricCollected(16, 48, 32, 16, true, false, 60.0f) sut.onFrameMetricCollected(60, 92, 32, 16, true, false, 60.0f) - sut.onFrameMetricCollected(100, 800, 800, 784, true, true, 60.0f) + sut.onFrameMetricCollected(100, 800, 700, 784, true, true, 60.0f) // then a second span starts fixture.timeNanos = 800 @@ -337,10 +337,11 @@ class SpanFrameMetricsCollectorTest { fixture.timeNanos = TimeUnit.SECONDS.toNanos(2) sut.onSpanFinished(span) - // then still 60 frames should be reported (1 second at 60fps) - verify(span).setData("frames.total", 60) + // then still 61 frames should be reported (1 second at 60fps with approximation) + verify(span).setData("frames.total", 61) verify(span).setData("frames.slow", 0) verify(span).setData("frames.frozen", 0) + verify(span).setData("frames.delay", 0.0) } @Test @@ -364,9 +365,9 @@ class SpanFrameMetricsCollectorTest { sut.onSpanFinished(span) // then - // still 60 fps should be reported for 1 seconds + // still 61 fps should be reported for 1 seconds (with approximation) // and one frame with frame delay should be reported (1s - 16ms) - verify(span).setData("frames.total", 61) + verify(span).setData("frames.total", 62) verify(span).setData("frames.slow", 0) verify(span).setData("frames.frozen", 1) verify(span).setData(eq("frames.delay"), AdditionalMatchers.eq(0.983333334, 0.01))