Skip to content

Commit

Permalink
Merge pull request #2424 from DataDog/mconstantin/rum-7174/add-timing…
Browse files Browse the repository at this point in the history
…-strategy-for-ttns-requests-identification

RUM-7174 Introduce the setNetworkSettledInitialResourceIdentifier API
  • Loading branch information
mariusc83 committed Dec 4, 2024
2 parents 614e7c0 + 48ab0a2 commit 2acc626
Show file tree
Hide file tree
Showing 31 changed files with 438 additions and 140 deletions.
11 changes: 11 additions & 0 deletions features/dd-sdk-android-rum/api/apiSurface
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ data class com.datadog.android.rum.RumConfiguration
fun setVitalsUpdateFrequency(com.datadog.android.rum.configuration.VitalsUpdateFrequency): Builder
fun useCustomEndpoint(String): Builder
fun setSessionListener(RumSessionListener): Builder
fun setInitialResourceIdentifier(com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier): Builder
fun build(): RumConfiguration
enum com.datadog.android.rum.RumErrorSource
- NETWORK
Expand Down Expand Up @@ -174,6 +175,16 @@ interface com.datadog.android.rum.internal.monitor.AdvancedNetworkRumMonitor : c
fun stopResource(com.datadog.android.rum.resource.ResourceId, Int?, Long?, com.datadog.android.rum.RumResourceKind, Map<String, Any?>)
fun stopResourceWithError(com.datadog.android.rum.resource.ResourceId, Int?, String, com.datadog.android.rum.RumErrorSource, Throwable, Map<String, Any?> = emptyMap())
fun stopResourceWithError(com.datadog.android.rum.resource.ResourceId, Int?, String, com.datadog.android.rum.RumErrorSource, String, String?, Map<String, Any?> = emptyMap())
interface com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier
fun validate(NetworkSettledResourceContext): Boolean
data class com.datadog.android.rum.metric.networksettled.NetworkSettledResourceContext
constructor(String, Long, Long?)
class com.datadog.android.rum.metric.networksettled.TimeBasedInitialResourceIdentifier : InitialResourceIdentifier
constructor(Long = DEFAULT_TIME_THRESHOLD_MS)
override fun validate(NetworkSettledResourceContext): Boolean
override fun equals(Any?): Boolean
override fun hashCode(): Int
companion object
fun android.content.Context.getAssetAsRumResource(String, Int = AssetManager.ACCESS_STREAMING, com.datadog.android.api.SdkCore = Datadog.getInstance()): java.io.InputStream
fun android.content.Context.getRawResAsRumResource(Int, com.datadog.android.api.SdkCore = Datadog.getInstance()): java.io.InputStream
fun java.io.InputStream.asRumResource(String, com.datadog.android.api.SdkCore = Datadog.getInstance()): java.io.InputStream
Expand Down
27 changes: 27 additions & 0 deletions features/dd-sdk-android-rum/api/dd-sdk-android-rum.api
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public final class com/datadog/android/rum/RumConfiguration$Builder {
public final fun disableUserInteractionTracking ()Lcom/datadog/android/rum/RumConfiguration$Builder;
public final fun setActionEventMapper (Lcom/datadog/android/event/EventMapper;)Lcom/datadog/android/rum/RumConfiguration$Builder;
public final fun setErrorEventMapper (Lcom/datadog/android/event/EventMapper;)Lcom/datadog/android/rum/RumConfiguration$Builder;
public final fun setInitialResourceIdentifier (Lcom/datadog/android/rum/metric/networksettled/InitialResourceIdentifier;)Lcom/datadog/android/rum/RumConfiguration$Builder;
public final fun setLongTaskEventMapper (Lcom/datadog/android/event/EventMapper;)Lcom/datadog/android/rum/RumConfiguration$Builder;
public final fun setResourceEventMapper (Lcom/datadog/android/event/EventMapper;)Lcom/datadog/android/rum/RumConfiguration$Builder;
public final fun setSessionListener (Lcom/datadog/android/rum/RumSessionListener;)Lcom/datadog/android/rum/RumConfiguration$Builder;
Expand Down Expand Up @@ -303,6 +304,32 @@ public final class com/datadog/android/rum/internal/monitor/AdvancedNetworkRumMo
public static synthetic fun stopResourceWithError$default (Lcom/datadog/android/rum/internal/monitor/AdvancedNetworkRumMonitor;Lcom/datadog/android/rum/resource/ResourceId;Ljava/lang/Integer;Ljava/lang/String;Lcom/datadog/android/rum/RumErrorSource;Ljava/lang/Throwable;Ljava/util/Map;ILjava/lang/Object;)V
}

public abstract interface class com/datadog/android/rum/metric/networksettled/InitialResourceIdentifier {
public abstract fun validate (Lcom/datadog/android/rum/metric/networksettled/NetworkSettledResourceContext;)Z
}

public final class com/datadog/android/rum/metric/networksettled/NetworkSettledResourceContext {
public fun <init> (Ljava/lang/String;JLjava/lang/Long;)V
public final fun copy (Ljava/lang/String;JLjava/lang/Long;)Lcom/datadog/android/rum/metric/networksettled/NetworkSettledResourceContext;
public static synthetic fun copy$default (Lcom/datadog/android/rum/metric/networksettled/NetworkSettledResourceContext;Ljava/lang/String;JLjava/lang/Long;ILjava/lang/Object;)Lcom/datadog/android/rum/metric/networksettled/NetworkSettledResourceContext;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/datadog/android/rum/metric/networksettled/TimeBasedInitialResourceIdentifier : com/datadog/android/rum/metric/networksettled/InitialResourceIdentifier {
public static final field Companion Lcom/datadog/android/rum/metric/networksettled/TimeBasedInitialResourceIdentifier$Companion;
public fun <init> ()V
public fun <init> (J)V
public synthetic fun <init> (JILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public fun validate (Lcom/datadog/android/rum/metric/networksettled/NetworkSettledResourceContext;)Z
}

public final class com/datadog/android/rum/metric/networksettled/TimeBasedInitialResourceIdentifier$Companion {
}

public final class com/datadog/android/rum/model/ActionEvent {
public static final field Companion Lcom/datadog/android/rum/model/ActionEvent$Companion;
public fun <init> (JLcom/datadog/android/rum/model/ActionEvent$Application;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSession;Lcom/datadog/android/rum/model/ActionEvent$ActionEventSource;Lcom/datadog/android/rum/model/ActionEvent$ActionEventView;Lcom/datadog/android/rum/model/ActionEvent$Usr;Lcom/datadog/android/rum/model/ActionEvent$Connectivity;Lcom/datadog/android/rum/model/ActionEvent$Display;Lcom/datadog/android/rum/model/ActionEvent$Synthetics;Lcom/datadog/android/rum/model/ActionEvent$CiTest;Lcom/datadog/android/rum/model/ActionEvent$Os;Lcom/datadog/android/rum/model/ActionEvent$Device;Lcom/datadog/android/rum/model/ActionEvent$Dd;Lcom/datadog/android/rum/model/ActionEvent$Context;Lcom/datadog/android/rum/model/ActionEvent$Container;Lcom/datadog/android/rum/model/ActionEvent$ActionEventAction;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ object Rum {
backgroundTrackingEnabled = rumFeature.backgroundEventTracking,
trackFrustrations = rumFeature.trackFrustrations,
sessionListener = rumFeature.sessionListener,
executorService = sdkCore.createSingleThreadExecutorService("rum-pipeline")
executorService = sdkCore.createSingleThreadExecutorService("rum-pipeline"),
initialResourceIdentifier = rumFeature.initialResourceIdentifier
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import com.datadog.android.rum.event.ViewEventMapper
import com.datadog.android.rum.internal.RumFeature
import com.datadog.android.rum.internal.instrumentation.MainLooperLongTaskStrategy
import com.datadog.android.rum.internal.tracking.NoOpInteractionPredicate
import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier
import com.datadog.android.rum.metric.networksettled.TimeBasedInitialResourceIdentifier
import com.datadog.android.rum.model.ActionEvent
import com.datadog.android.rum.model.ErrorEvent
import com.datadog.android.rum.model.LongTaskEvent
Expand Down Expand Up @@ -257,6 +259,17 @@ data class RumConfiguration internal constructor(
return this
}

/**
* Sets the identifier strategy for initial network resources used to compute the time to network settled
* in a RUM View event. By default, the SDK uses a [TimeBasedInitialResourceIdentifier] with
* a threshold of 100ms.
* @param initialResourceIdentifier the [InitialResourceIdentifier] to use.
*/
fun setInitialResourceIdentifier(initialResourceIdentifier: InitialResourceIdentifier): Builder {
rumConfig = rumConfig.copy(initialResourceIdentifier = initialResourceIdentifier)
return this
}

/**
* Builds a [RumConfiguration] based on the current state of this Builder.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ import com.datadog.android.rum.internal.vitals.VitalMonitor
import com.datadog.android.rum.internal.vitals.VitalObserver
import com.datadog.android.rum.internal.vitals.VitalReader
import com.datadog.android.rum.internal.vitals.VitalReaderRunnable
import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier
import com.datadog.android.rum.metric.networksettled.NoOpInitialResourceIdentifier
import com.datadog.android.rum.metric.networksettled.TimeBasedInitialResourceIdentifier
import com.datadog.android.rum.model.ActionEvent
import com.datadog.android.rum.model.ErrorEvent
import com.datadog.android.rum.model.LongTaskEvent
Expand Down Expand Up @@ -127,6 +130,7 @@ internal class RumFeature(
private var anrDetectorExecutorService: ExecutorService? = null
internal var anrDetectorRunnable: ANRDetectorRunnable? = null
internal lateinit var appContext: Context
internal var initialResourceIdentifier: InitialResourceIdentifier = NoOpInitialResourceIdentifier()

private val lateCrashEventHandler by lazy { lateCrashReporterFactory(sdkCore as InternalSdkCore) }

Expand All @@ -136,7 +140,7 @@ internal class RumFeature(

override fun onInitialize(appContext: Context) {
this.appContext = appContext

initialResourceIdentifier = configuration.initialResourceIdentifier
dataWriter = createDataWriter(
configuration,
sdkCore as InternalSdkCore
Expand Down Expand Up @@ -530,6 +534,7 @@ internal class RumFeature(
val trackNonFatalAnrs: Boolean,
val vitalsMonitorUpdateFrequency: VitalsUpdateFrequency,
val sessionListener: RumSessionListener,
val initialResourceIdentifier: InitialResourceIdentifier,
val additionalConfig: Map<String, Any>
)

Expand Down Expand Up @@ -573,6 +578,7 @@ internal class RumFeature(
trackNonFatalAnrs = isTrackNonFatalAnrsEnabledByDefault(),
vitalsMonitorUpdateFrequency = VitalsUpdateFrequency.AVERAGE,
sessionListener = NoOpRumSessionListener(),
initialResourceIdentifier = TimeBasedInitialResourceIdentifier(),
additionalConfig = emptyMap()
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import com.datadog.android.rum.RumActionType
import com.datadog.android.rum.internal.FeaturesContextResolver
import com.datadog.android.rum.internal.domain.RumContext
import com.datadog.android.rum.internal.domain.Time
import com.datadog.android.rum.internal.metric.interactiontonextview.InteractionToNextViewMetricResolver
import com.datadog.android.rum.internal.metric.interactiontonextview.InternalInteractionContext
import com.datadog.android.rum.internal.monitor.StorageEvent
import com.datadog.android.rum.internal.utils.hasUserData
import com.datadog.android.rum.internal.utils.newRumEventWriteOperation
Expand All @@ -36,7 +38,8 @@ internal class RumActionScope(
maxDurationMs: Long = ACTION_MAX_DURATION_MS,
private val featuresContextResolver: FeaturesContextResolver = FeaturesContextResolver(),
private val trackFrustrations: Boolean,
internal val sampleRate: Float
internal val sampleRate: Float,
private val interactionToNextViewMetricResolver: InteractionToNextViewMetricResolver
) : RumScope {

private val inactivityThresholdNs = TimeUnit.MILLISECONDS.toNanos(inactivityThresholdMs)
Expand Down Expand Up @@ -215,6 +218,8 @@ internal class RumActionScope(
val eventCrashCount = crashCount
val eventLongTaskCount = longTaskCount
val eventResourceCount = resourceCount
val viewId = getRumContext().viewId.orEmpty()
val actionDuration = max(endNanos - startedNanos, 1L)

val syntheticsAttribute = if (
rumContext.syntheticsTestId.isNullOrBlank() ||
Expand Down Expand Up @@ -254,15 +259,15 @@ internal class RumActionScope(
crash = ActionEvent.Crash(eventCrashCount),
longTask = ActionEvent.LongTask(eventLongTaskCount),
resource = ActionEvent.Resource(eventResourceCount),
loadingTime = max(endNanos - startedNanos, 1L),
loadingTime = actionDuration,
frustration = if (frustrations.isNotEmpty()) {
ActionEvent.Frustration(frustrations)
} else {
null
}
),
view = ActionEvent.ActionEventView(
id = rumContext.viewId.orEmpty(),
id = viewId,
name = rumContext.viewName,
url = rumContext.viewUrl.orEmpty()
),
Expand Down Expand Up @@ -318,6 +323,14 @@ internal class RumActionScope(
}
onSuccess {
it.eventSent(rumContext.viewId.orEmpty(), storageEvent)
val eventTimestampAsNanos = TimeUnit.MILLISECONDS.toNanos(eventTimestamp)
interactionToNextViewMetricResolver.onActionSent(
InternalInteractionContext(
actionType = actualType,
viewId = viewId,
eventCreatedAtNanos = eventTimestampAsNanos + actionDuration
)
)
}
}
.submit()
Expand All @@ -339,7 +352,8 @@ internal class RumActionScope(
timestampOffset: Long,
featuresContextResolver: FeaturesContextResolver,
trackFrustrations: Boolean,
sampleRate: Float
sampleRate: Float,
interactionToNextViewMetricResolver: InteractionToNextViewMetricResolver
): RumScope {
return RumActionScope(
parentScope,
Expand All @@ -352,7 +366,8 @@ internal class RumActionScope(
timestampOffset,
featuresContextResolver = featuresContextResolver,
trackFrustrations = trackFrustrations,
sampleRate = sampleRate
sampleRate = sampleRate,
interactionToNextViewMetricResolver = interactionToNextViewMetricResolver
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.datadog.android.rum.internal.domain.RumContext
import com.datadog.android.rum.internal.domain.Time
import com.datadog.android.rum.internal.metric.SessionMetricDispatcher
import com.datadog.android.rum.internal.vitals.VitalMonitor
import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier
import java.util.concurrent.TimeUnit

@Suppress("LongParameterList")
Expand All @@ -33,7 +34,8 @@ internal class RumApplicationScope(
private val memoryVitalMonitor: VitalMonitor,
private val frameRateVitalMonitor: VitalMonitor,
private val sessionEndedMetricDispatcher: SessionMetricDispatcher,
private val sessionListener: RumSessionListener?
private val sessionListener: RumSessionListener?,
private val initialResourceIdentifier: InitialResourceIdentifier
) : RumScope, RumViewChangedListener {

private var rumContext = RumContext(applicationId = applicationId)
Expand All @@ -52,7 +54,8 @@ internal class RumApplicationScope(
memoryVitalMonitor,
frameRateVitalMonitor,
sessionListener,
false
false,
initialResourceIdentifier
)
)

Expand Down Expand Up @@ -144,7 +147,8 @@ internal class RumApplicationScope(
memoryVitalMonitor,
frameRateVitalMonitor,
sessionListener,
true
true,
initialResourceIdentifier
)
childScopes.add(newSession)
if (event !is RumRawEvent.StartView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import com.datadog.android.rum.internal.domain.RumContext
import com.datadog.android.rum.internal.metric.SessionMetricDispatcher
import com.datadog.android.rum.internal.utils.percent
import com.datadog.android.rum.internal.vitals.VitalMonitor
import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier
import java.security.SecureRandom
import java.util.UUID
import java.util.concurrent.TimeUnit
Expand All @@ -37,6 +38,7 @@ internal class RumSessionScope(
frameRateVitalMonitor: VitalMonitor,
private val sessionListener: RumSessionListener?,
applicationDisplayed: Boolean,
networkSettledResourceIdentifier: InitialResourceIdentifier,
private val sessionInactivityNanos: Long = DEFAULT_SESSION_INACTIVITY_NS,
private val sessionMaxDurationNanos: Long = DEFAULT_SESSION_MAX_DURATION_NS
) : RumScope {
Expand Down Expand Up @@ -66,7 +68,8 @@ internal class RumSessionScope(
memoryVitalMonitor,
frameRateVitalMonitor,
applicationDisplayed,
sampleRate
sampleRate,
networkSettledResourceIdentifier
)

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import com.datadog.android.rum.internal.domain.Time
import com.datadog.android.rum.internal.metric.SessionEndedMetric
import com.datadog.android.rum.internal.metric.SessionMetricDispatcher
import com.datadog.android.rum.internal.metric.interactiontonextview.InteractionToNextViewMetricResolver
import com.datadog.android.rum.internal.metric.networksettled.NetworkSettledMetricResolver
import com.datadog.android.rum.internal.vitals.NoOpVitalMonitor
import com.datadog.android.rum.internal.vitals.VitalMonitor
import com.datadog.android.rum.metric.networksettled.InitialResourceIdentifier
import java.util.Locale
import java.util.concurrent.TimeUnit

Expand All @@ -40,6 +42,7 @@ internal class RumViewManagerScope(
private val frameRateVitalMonitor: VitalMonitor,
internal var applicationDisplayed: Boolean,
internal val sampleRate: Float,
internal val initialResourceIdentifier: InitialResourceIdentifier,
private val interactionToNextViewMetricResolver: InteractionToNextViewMetricResolver =
InteractionToNextViewMetricResolver(internalLogger = sdkCore.internalLogger)
) : RumScope {
Expand Down Expand Up @@ -202,7 +205,8 @@ internal class RumViewManagerScope(
frameRateVitalMonitor,
trackFrustrations,
sampleRate,
interactionToNextViewMetricResolver
interactionToNextViewMetricResolver,
initialResourceIdentifier
)
applicationDisplayed = true
childrenScopes.add(viewScope)
Expand Down Expand Up @@ -265,7 +269,11 @@ internal class RumViewManagerScope(
type = RumViewScope.RumViewType.BACKGROUND,
trackFrustrations = trackFrustrations,
sampleRate = sampleRate,
interactionToNextViewMetricResolver = interactionToNextViewMetricResolver
interactionToNextViewMetricResolver = interactionToNextViewMetricResolver,
networkSettledMetricResolver = NetworkSettledMetricResolver(
initialResourceIdentifier,
sdkCore.internalLogger
)
)
}

Expand All @@ -289,7 +297,11 @@ internal class RumViewManagerScope(
type = RumViewScope.RumViewType.APPLICATION_LAUNCH,
trackFrustrations = trackFrustrations,
sampleRate = sampleRate,
interactionToNextViewMetricResolver = interactionToNextViewMetricResolver
interactionToNextViewMetricResolver = interactionToNextViewMetricResolver,
networkSettledMetricResolver = NetworkSettledMetricResolver(
initialResourceIdentifier,
sdkCore.internalLogger
)
)
}

Expand Down
Loading

0 comments on commit 2acc626

Please sign in to comment.