Skip to content

Commit 70aa8cc

Browse files
committed
RUM-10409: fix effective sample rate calculation for SessionEndedMetricDispatcher
1 parent 02249ad commit 70aa8cc

File tree

3 files changed

+55
-11
lines changed

3 files changed

+55
-11
lines changed

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/Rum.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import com.datadog.android.rum.internal.RumAnonymousIdentifierManager
2020
import com.datadog.android.rum.internal.RumFeature
2121
import com.datadog.android.rum.internal.metric.SessionEndedMetricDispatcher
2222
import com.datadog.android.rum.internal.monitor.DatadogRumMonitor
23+
import com.datadog.android.rum.internal.utils.percent
2324
import com.datadog.android.telemetry.internal.TelemetryEventHandler
2425

2526
/**
@@ -109,7 +110,11 @@ object Rum {
109110
sdkCore: InternalSdkCore,
110111
rumFeature: RumFeature
111112
): DatadogRumMonitor {
112-
val sessionEndedMetricDispatcher = SessionEndedMetricDispatcher(internalLogger = sdkCore.internalLogger)
113+
val sessionEndedMetricDispatcher = SessionEndedMetricDispatcher(
114+
internalLogger = sdkCore.internalLogger,
115+
sessionSamplingRate = rumFeature.configuration.sampleRate.percent().toFloat()
116+
)
117+
113118
return DatadogRumMonitor(
114119
applicationId = rumFeature.applicationId,
115120
sdkCore = sdkCore,

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/metric/SessionEndedMetricDispatcher.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import com.datadog.android.rum.internal.domain.scope.RumViewManagerScope
1212
import com.datadog.android.rum.model.ViewEvent
1313
import java.util.concurrent.ConcurrentHashMap
1414

15-
internal class SessionEndedMetricDispatcher(private val internalLogger: InternalLogger) :
15+
internal class SessionEndedMetricDispatcher(
16+
private val internalLogger: InternalLogger,
17+
private val sessionSamplingRate: Float
18+
) :
1619
SessionMetricDispatcher {
1720

1821
private val metricsBySessionId = ConcurrentHashMap<String, SessionEndedMetric>()
@@ -38,6 +41,7 @@ internal class SessionEndedMetricDispatcher(private val internalLogger: Internal
3841
internalLogger.logMetric(
3942
messageBuilder = { SessionEndedMetric.RUM_SESSION_ENDED_METRIC_NAME },
4043
additionalProperties = metric.toMetricAttributes(ntpOffsetAtEndMs),
44+
creationSampleRate = sessionSamplingRate,
4145
samplingRate = 15.0f
4246
)
4347
}

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/metric/SessionEndedMetricDispatcherTest.kt

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66

77
package com.datadog.android.rum.internal.metric
88

9+
import com.datadog.android.api.InternalLogger
910
import com.datadog.android.rum.internal.domain.scope.RumSessionScope
1011
import com.datadog.android.rum.model.ViewEvent
1112
import com.datadog.android.rum.utils.forge.Configurator
1213
import com.datadog.tools.unit.extensions.TestConfigurationExtension
1314
import fr.xgouchet.elmyr.annotation.BoolForgery
15+
import fr.xgouchet.elmyr.annotation.FloatForgery
1416
import fr.xgouchet.elmyr.annotation.Forgery
1517
import fr.xgouchet.elmyr.annotation.IntForgery
1618
import fr.xgouchet.elmyr.annotation.LongForgery
@@ -21,8 +23,12 @@ import org.assertj.core.api.Assertions.assertThat
2123
import org.junit.jupiter.api.Test
2224
import org.junit.jupiter.api.extension.ExtendWith
2325
import org.junit.jupiter.api.extension.Extensions
26+
import org.mockito.Mockito.mock
2427
import org.mockito.junit.jupiter.MockitoExtension
2528
import org.mockito.junit.jupiter.MockitoSettings
29+
import org.mockito.kotlin.any
30+
import org.mockito.kotlin.eq
31+
import org.mockito.kotlin.verify
2632
import org.mockito.quality.Strictness
2733

2834
@Extensions(
@@ -48,10 +54,13 @@ internal class SessionEndedMetricDispatcherTest {
4854
@BoolForgery
4955
private var backgroundEventTracking: Boolean = false
5056

57+
@FloatForgery(min = 0f, max = 100f)
58+
private var fakeSessionSampleRate: Float = 1f
59+
5160
@Test
5261
fun `M register session stop W call onSessionStopped()`(@StringForgery fakeSessionId: String) {
5362
// Given
54-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
63+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
5564
dispatcher.startMetric(
5665
fakeSessionId,
5766
fakeStartReason,
@@ -74,7 +83,7 @@ internal class SessionEndedMetricDispatcherTest {
7483
@Forgery viewEvent: ViewEvent
7584
) {
7685
// Given
77-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
86+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
7887

7988
// When
8089
dispatcher.startMetric(
@@ -109,7 +118,7 @@ internal class SessionEndedMetricDispatcherTest {
109118
@Forgery viewEvents: List<ViewEvent>
110119
) {
111120
// Given
112-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
121+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
113122

114123
// When
115124
dispatcher.startMetric(
@@ -166,7 +175,7 @@ internal class SessionEndedMetricDispatcherTest {
166175
@StringForgery errorKinds: List<String>
167176
) {
168177
// Given
169-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
178+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
170179

171180
// When
172181
dispatcher.startMetric(
@@ -218,7 +227,7 @@ internal class SessionEndedMetricDispatcherTest {
218227
@Forgery viewEvents: List<ViewEvent>
219228
) {
220229
// Given
221-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
230+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
222231

223232
// When
224233
dispatcher.startMetric(
@@ -243,7 +252,7 @@ internal class SessionEndedMetricDispatcherTest {
243252
@Forgery missedTypes: List<SessionEndedMetric.MissedEventType>
244253
) {
245254
// Given
246-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
255+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
247256

248257
// When
249258
dispatcher.startMetric(
@@ -295,7 +304,7 @@ internal class SessionEndedMetricDispatcherTest {
295304
Boolean
296305
) {
297306
// Given
298-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
307+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
299308

300309
// When
301310
dispatcher.startMetric(
@@ -317,7 +326,7 @@ internal class SessionEndedMetricDispatcherTest {
317326
@LongForgery fakeNtpOffsetAtEnd: Long
318327
) {
319328
// Given
320-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
329+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
321330

322331
// When
323332
dispatcher.startMetric(
@@ -339,7 +348,7 @@ internal class SessionEndedMetricDispatcherTest {
339348
@IntForgery(min = 0, max = 100) skippedFramesCount: Int
340349
) {
341350
// Given
342-
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger)
351+
val dispatcher = SessionEndedMetricDispatcher(fakeInternalLogger, fakeSessionSampleRate)
343352

344353
// When
345354
dispatcher.startMetric(
@@ -357,6 +366,32 @@ internal class SessionEndedMetricDispatcherTest {
357366
assertThat(fakeInternalLogger.getSkippedFramesCount()).isEqualTo(skippedFramesCount)
358367
}
359368

369+
@Test
370+
fun `M has creationSamplingRate AND samplingRate W end metric`(
371+
@StringForgery fakeSessionId: String
372+
) {
373+
// Given
374+
val mockInternalLogger = mock<InternalLogger>()
375+
val dispatcher = SessionEndedMetricDispatcher(mockInternalLogger, fakeSessionSampleRate)
376+
377+
// When
378+
dispatcher.startMetric(
379+
fakeSessionId,
380+
fakeStartReason,
381+
fakeNtpOffsetAtStart,
382+
backgroundEventTracking
383+
)
384+
dispatcher.endMetric(fakeSessionId, fakeNtpOffsetAtEnd)
385+
386+
// Then
387+
verify(mockInternalLogger).logMetric(
388+
any(),
389+
any(),
390+
eq(15.0f),
391+
eq(fakeSessionSampleRate)
392+
)
393+
}
394+
360395
private fun FakeInternalLogger.getNtpAtStartOffset(): Long {
361396
return lastMetric?.second?.let { attributes ->
362397
val rse = attributes[SessionEndedMetric.RSE_KEY] as Map<*, *>

0 commit comments

Comments
 (0)