Skip to content

Commit 01719ec

Browse files
committed
RUM-12923: Attach RUM information on profiling event
1 parent 3d91afb commit 01719ec

File tree

15 files changed

+153
-34
lines changed

15 files changed

+153
-34
lines changed

dd-sdk-android-internal/api/apiSurface

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,6 @@ class com.datadog.android.rum.DdRumContentProvider : android.content.ContentProv
158158
var processImportance: Int
159159
val createTimeNs: Long
160160
data class com.datadog.android.rum.TTIDEvent
161-
constructor(Long)
161+
constructor(Long, String, String, String, String?, String?)
162162
annotation com.datadog.tools.annotation.NoOpImplementation
163163
constructor(Boolean = false)

dd-sdk-android-internal/api/dd-sdk-android-internal.api

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,12 +382,22 @@ public final class com/datadog/android/rum/DdRumContentProvider$Companion {
382382
}
383383

384384
public final class com/datadog/android/rum/TTIDEvent {
385-
public fun <init> (J)V
385+
public fun <init> (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
386386
public final fun component1 ()J
387-
public final fun copy (J)Lcom/datadog/android/rum/TTIDEvent;
388-
public static synthetic fun copy$default (Lcom/datadog/android/rum/TTIDEvent;JILjava/lang/Object;)Lcom/datadog/android/rum/TTIDEvent;
387+
public final fun component2 ()Ljava/lang/String;
388+
public final fun component3 ()Ljava/lang/String;
389+
public final fun component4 ()Ljava/lang/String;
390+
public final fun component5 ()Ljava/lang/String;
391+
public final fun component6 ()Ljava/lang/String;
392+
public final fun copy (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/datadog/android/rum/TTIDEvent;
393+
public static synthetic fun copy$default (Lcom/datadog/android/rum/TTIDEvent;JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/datadog/android/rum/TTIDEvent;
389394
public fun equals (Ljava/lang/Object;)Z
395+
public final fun getApplicationId ()Ljava/lang/String;
396+
public final fun getSessionId ()Ljava/lang/String;
390397
public final fun getValue ()J
398+
public final fun getViewId ()Ljava/lang/String;
399+
public final fun getViewName ()Ljava/lang/String;
400+
public final fun getVitalId ()Ljava/lang/String;
391401
public fun hashCode ()I
392402
public fun toString ()Ljava/lang/String;
393403
}

dd-sdk-android-internal/src/main/java/com/datadog/android/rum/TTIDEvent.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,17 @@ package com.datadog.android.rum
1010
* Internal event to pass the Time To Initial Display (TTID) value in nanoseconds.
1111
*
1212
* @param value The TTID value in nanoseconds.
13+
* @param applicationId The Id of the application of RUM.
14+
* @param sessionId The Id of the RUM session where TTID is captured
15+
* @param vitalId The Id of the TTID vital event
16+
* @param viewId The Id of the view where TTID is captured
17+
* @param viewName The name of the view where TTID is captured
1318
*/
14-
data class TTIDEvent(val value: Long)
19+
data class TTIDEvent(
20+
val value: Long,
21+
val applicationId: String,
22+
val sessionId: String,
23+
val vitalId: String,
24+
val viewId: String?,
25+
val viewName: String?
26+
)

dd-sdk-android-internal/src/test/java/com/datadog/android/internal/forge/Configurator.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package com.datadog.android.internal.forge
88

99
import com.datadog.android.internal.tests.elmyr.InternalTelemetryErrorLogForgeryFactory
10+
import com.datadog.android.internal.tests.elmyr.TTIDEventFactory
1011
import com.datadog.tools.unit.forge.BaseConfigurator
1112
import fr.xgouchet.elmyr.Forge
1213
import fr.xgouchet.elmyr.jvm.useJvmFactories
@@ -17,5 +18,6 @@ internal class Configurator :
1718
super.configure(forge)
1819
forge.useJvmFactories()
1920
forge.addFactory(InternalTelemetryErrorLogForgeryFactory())
21+
forge.addFactory(TTIDEventFactory())
2022
}
2123
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.internal.tests.elmyr
8+
9+
import com.datadog.android.rum.TTIDEvent
10+
import fr.xgouchet.elmyr.Forge
11+
import fr.xgouchet.elmyr.ForgeryFactory
12+
13+
class TTIDEventFactory : ForgeryFactory<TTIDEvent> {
14+
override fun getForgery(forge: Forge): TTIDEvent {
15+
return TTIDEvent(
16+
value = forge.aLong(),
17+
applicationId = forge.anAlphabeticalString(),
18+
sessionId = forge.anAlphabeticalString(),
19+
vitalId = forge.anAlphabeticalString(),
20+
viewId = forge.anAlphabeticalString(),
21+
viewName = forge.anAlphabeticalString()
22+
)
23+
}
24+
}

features/dd-sdk-android-profiling/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ dependencies {
6565
}
6666

6767
testImplementation(testFixtures(project(":dd-sdk-android-core")))
68+
testImplementation(testFixtures(project(":dd-sdk-android-internal")))
6869
testImplementation(libs.bundles.jUnit5)
6970
testImplementation(libs.bundles.testTools)
7071
unmock(libs.robolectric)

features/dd-sdk-android-profiling/src/main/java/com/datadog/android/profiling/internal/ProfilingDataWriter.kt

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,23 @@ import com.datadog.android.core.internal.persistence.file.readBytesSafe
1515
import com.datadog.android.internal.utils.formatIsoUtc
1616
import com.datadog.android.profiling.internal.perfetto.PerfettoResult
1717
import com.datadog.android.profiling.model.ProfileEvent
18+
import com.datadog.android.rum.TTIDEvent
1819
import java.io.File
1920

2021
internal class ProfilingDataWriter(
2122
private val sdkCore: FeatureSdkCore
2223
) : ProfilingWriter {
2324
override fun write(
24-
profilingResult: PerfettoResult
25+
profilingResult: PerfettoResult,
26+
ttidEvent: TTIDEvent?
2527
) {
2628
sdkCore.getFeature(Feature.PROFILING_FEATURE_NAME)
2729
?.withWriteContext { context, writeScope ->
2830
writeScope { writer ->
2931
val rawBatchEvent = buildRawBatchEvent(
3032
context = context,
31-
profilingResult = profilingResult
33+
profilingResult = profilingResult,
34+
ttidEvent = ttidEvent
3235
)
3336
if (rawBatchEvent != null) {
3437
synchronized(this) {
@@ -45,21 +48,27 @@ internal class ProfilingDataWriter(
4548

4649
private fun buildRawBatchEvent(
4750
context: DatadogContext,
48-
profilingResult: PerfettoResult
51+
profilingResult: PerfettoResult,
52+
ttidEvent: TTIDEvent?
4953
): RawBatchEvent? {
5054
val byteData = readProfilingData(profilingResult.resultFilePath)
5155
if (byteData == null || byteData.isEmpty()) {
5256
return null
5357
}
54-
val profileEvent = createProfileEvent(context, profilingResult)
58+
val profileEvent = createProfileEvent(
59+
context,
60+
profilingResult,
61+
ttidEvent
62+
)
5563
val serializedEvent =
5664
profileEvent.toJson().toString().toByteArray(Charsets.UTF_8)
5765
return RawBatchEvent(data = serializedEvent, metadata = byteData)
5866
}
5967

6068
private fun createProfileEvent(
6169
context: DatadogContext,
62-
profilingResult: PerfettoResult
70+
profilingResult: PerfettoResult,
71+
ttidEvent: TTIDEvent?
6372
): ProfileEvent {
6473
return ProfileEvent(
6574
start = formatIsoUtc(profilingResult.start),
@@ -68,18 +77,37 @@ internal class ProfilingDataWriter(
6877
family = ANDROID_FAMILY_NAME,
6978
runtime = ANDROID_RUNTIME_NAME,
7079
version = VERSION_NUMBER,
71-
tagsProfiler = buildTags(context)
80+
tagsProfiler = buildTags(context, ttidEvent)
7281
)
7382
}
7483

75-
private fun buildTags(context: DatadogContext): String = buildString {
84+
private fun buildTags(
85+
context: DatadogContext,
86+
ttidEvent: TTIDEvent?
87+
): String = buildString {
7688
append("$TAG_KEY_SERVICE:${context.service}")
7789
append(",")
7890
append("$TAG_KEY_ENV:${context.env}")
7991
append(",")
8092
append("$TAG_KEY_VERSION:${context.version}")
8193
append(",")
8294
append("$TAG_KEY_SDK_VERSION:${context.sdkVersion}")
95+
ttidEvent?.apply {
96+
append(",")
97+
append("$TAG_KEY_RUM_APPLICATION_ID:$applicationId")
98+
append(",")
99+
append("$TAG_KEY_RUM_SESSION_ID:$sessionId")
100+
append(",")
101+
append("$TAG_KEY_RUM_VITAL_ID:$vitalId")
102+
viewId?.let {
103+
append(",")
104+
append("$TAG_KEY_RUM_VIEW_ID:$it")
105+
}
106+
viewName?.let {
107+
append(",")
108+
append("$TAG_KEY_RUM_VIEW_NAME:$it")
109+
}
110+
}
83111
}
84112

85113
private fun readProfilingData(profilingPath: String): ByteArray? {
@@ -92,6 +120,11 @@ internal class ProfilingDataWriter(
92120
private const val TAG_KEY_SERVICE = "service"
93121
private const val TAG_KEY_VERSION = "version"
94122
private const val TAG_KEY_SDK_VERSION = "sdk_version"
123+
private const val TAG_KEY_RUM_APPLICATION_ID = "session_id"
124+
private const val TAG_KEY_RUM_SESSION_ID = "session_id"
125+
private const val TAG_KEY_RUM_VITAL_ID = "vital_id"
126+
private const val TAG_KEY_RUM_VIEW_ID = "view_id"
127+
private const val TAG_KEY_RUM_VIEW_NAME = "view_name"
95128
private const val TAG_KEY_ENV = "env"
96129
private const val PERFETTO_ATTACHMENT_NAME = "perfetto.proto"
97130
private const val ANDROID_FAMILY_NAME = "android"

features/dd-sdk-android-profiling/src/main/java/com/datadog/android/profiling/internal/ProfilingFeature.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ internal class ProfilingFeature(
2929

3030
private var dataWriter: ProfilingWriter = NoOpProfilingWriter()
3131

32+
private var ttidEvent: TTIDEvent? = null
33+
3234
override val requestFactory: RequestFactory = ProfilingRequestFactory(
3335
configuration.customEndpointUrl,
3436
sdkCore.internalLogger
@@ -44,7 +46,10 @@ internal class ProfilingFeature(
4446
profiler.apply {
4547
this.internalLogger = sdkCore.internalLogger
4648
this.onProfilingSuccess = { result ->
47-
dataWriter.write(profilingResult = result)
49+
dataWriter.write(
50+
profilingResult = result,
51+
ttidEvent = ttidEvent
52+
)
4853
}
4954
}
5055
// Set the profiling flag in SharedPreferences to profile for the next app launch
@@ -67,6 +72,7 @@ internal class ProfilingFeature(
6772
)
6873
return
6974
}
75+
this.ttidEvent = event
7076
profiler.stop()
7177
sdkCore.internalLogger.log(
7278
InternalLogger.Level.INFO,

features/dd-sdk-android-profiling/src/main/java/com/datadog/android/profiling/internal/ProfilingWriter.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
package com.datadog.android.profiling.internal
88

99
import com.datadog.android.profiling.internal.perfetto.PerfettoResult
10+
import com.datadog.android.rum.TTIDEvent
1011
import com.datadog.tools.annotation.NoOpImplementation
1112

1213
@NoOpImplementation
1314
internal interface ProfilingWriter {
1415

1516
fun write(
16-
profilingResult: PerfettoResult
17+
profilingResult: PerfettoResult,
18+
ttidEvent: TTIDEvent?
1719
)
1820
}

features/dd-sdk-android-profiling/src/test/kotlin/com/datadog/android/profiling/ProfilingFeatureTest.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import com.datadog.android.profiling.internal.ProfilingFeature
1717
import com.datadog.android.profiling.internal.ProfilingRequestFactory
1818
import com.datadog.android.rum.TTIDEvent
1919
import fr.xgouchet.elmyr.annotation.Forgery
20-
import fr.xgouchet.elmyr.annotation.LongForgery
2120
import fr.xgouchet.elmyr.annotation.StringForgery
2221
import fr.xgouchet.elmyr.junit5.ForgeConfiguration
2322
import fr.xgouchet.elmyr.junit5.ForgeExtension
@@ -110,9 +109,11 @@ class ProfilingFeatureTest {
110109
}
111110

112111
@Test
113-
fun `M stop Profiling W receive TTID event`(@LongForgery fakeTtid: Long) {
112+
fun `M stop Profiling W receive TTID event`(
113+
@Forgery fakeTTIDEvent: TTIDEvent
114+
) {
114115
// When
115-
testedFeature.onReceive(TTIDEvent(fakeTtid))
116+
testedFeature.onReceive(fakeTTIDEvent)
116117

117118
// Then
118119
verify(mockProfiler).stop()

0 commit comments

Comments
 (0)