Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
### Improvements

- [ANR] Defer some class availability checks ([#4825](https://github.com/getsentry/sentry-java/pull/4825))
- Collect PerformanceCollectionData only for sampled transactions ([#4834](https://github.com/getsentry/sentry-java/pull/4834))
- **Breaking change**: Transactions with a deferred sampling decision (`sampled == null`) won't be collecting any performance data anymore (CPU, RAM, slow/frozen frames).

### Dependencies

Expand Down
10 changes: 6 additions & 4 deletions sentry/src/main/java/io/sentry/SentryTracer.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ public SentryTracer(
this.name = context.getName();
this.instrumenter = context.getInstrumenter();
this.scopes = scopes;
this.compositePerformanceCollector = compositePerformanceCollector;
// Let's collect performance data (cpu, ram, frames) only when the transaction is sampled
this.compositePerformanceCollector =
Boolean.TRUE.equals(isSampled()) ? compositePerformanceCollector : null;
this.transactionNameSource = context.getTransactionNameSource();
this.transactionOptions = transactionOptions;

Expand All @@ -90,9 +92,9 @@ public SentryTracer(
}

// We are currently sending the performance data only in profiles, but we are always sending
// performance measurements.
if (compositePerformanceCollector != null) {
compositePerformanceCollector.start(this);
// performance measurements (frames data in spans).
if (this.compositePerformanceCollector != null) {
this.compositePerformanceCollector.start(this);
}

if (transactionOptions.getIdleTimeout() != null
Expand Down
32 changes: 28 additions & 4 deletions sentry/src/test/java/io/sentry/SentryTracerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.sentry.protocol.SentryId
import io.sentry.protocol.TransactionNameSource
import io.sentry.protocol.User
import io.sentry.test.createTestScopes
import io.sentry.test.getProperty
import io.sentry.util.thread.IThreadChecker
import java.time.LocalDateTime
import java.time.ZoneOffset
Expand Down Expand Up @@ -1170,9 +1171,20 @@ class SentryTracerTest {
}

@Test
fun `when transaction is created, but not profiled, compositePerformanceCollector is started anyway`() {
val transaction = fixture.getSut()
fun `when transaction is created and sampled, but not profiled, compositePerformanceCollector is started anyway`() {
val transaction = fixture.getSut(samplingDecision = TracesSamplingDecision(true))
verify(fixture.compositePerformanceCollector).start(anyOrNull<ITransaction>())
assertEquals(
fixture.compositePerformanceCollector,
transaction.getProperty("compositePerformanceCollector"),
)
}

@Test
fun `when transaction is created, but not sampled, compositePerformanceCollector is not started nor set`() {
val transaction = fixture.getSut(samplingDecision = TracesSamplingDecision(false))
verify(fixture.compositePerformanceCollector, never()).start(anyOrNull<ITransaction>())
assertNull(transaction.getProperty("compositePerformanceCollector"))
}

@Test
Expand All @@ -1188,15 +1200,15 @@ class SentryTracerTest {

@Test
fun `when transaction is finished, compositePerformanceCollector is stopped`() {
val transaction = fixture.getSut()
val transaction = fixture.getSut(samplingDecision = TracesSamplingDecision(true))
transaction.finish()
verify(fixture.compositePerformanceCollector)
.stop(check<ITransaction> { assertEquals(transaction, it) })
}

@Test
fun `when a span is started and finished the compositePerformanceCollector gets notified`() {
val transaction = fixture.getSut()
val transaction = fixture.getSut(samplingDecision = TracesSamplingDecision(true))

val span = transaction.startChild("op.span")
span.finish()
Expand All @@ -1205,6 +1217,17 @@ class SentryTracerTest {
verify(fixture.compositePerformanceCollector).onSpanFinished(check { assertEquals(span, it) })
}

@Test
fun `when a span is started and finished the compositePerformanceCollector gets never notified if not sampled`() {
val transaction = fixture.getSut(samplingDecision = TracesSamplingDecision(false))

val span = transaction.startChild("op.span")
span.finish()

verify(fixture.compositePerformanceCollector, never()).onSpanStarted(any())
verify(fixture.compositePerformanceCollector, never()).onSpanFinished(any())
}

@Test
fun `changing transaction name without source sets source to custom`() {
val transaction = fixture.getSut()
Expand Down Expand Up @@ -1393,6 +1416,7 @@ class SentryTracerTest {
}
val transaction =
fixture.getSut(
samplingDecision = TracesSamplingDecision(true),
optionsConfiguration = { it.profilesSampleRate = 1.0 },
performanceCollector = mockPerformanceCollector,
)
Expand Down
Loading