Skip to content

Commit c932cc3

Browse files
committed
RUM-9908 Propagate View attributes
1 parent 255ddc2 commit c932cc3

File tree

6 files changed

+716
-1025
lines changed

6 files changed

+716
-1025
lines changed

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumScope.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import androidx.annotation.WorkerThread
1010
import com.datadog.android.api.storage.DataWriter
1111
import com.datadog.android.rum.internal.domain.RumContext
1212

13-
@NoOpImplementation
1413
internal interface RumScope {
1514

1615
val parentScope: RumScope?

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewScope.kt

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import com.datadog.android.core.internal.attributes.ViewScopeInstrumentationType
1818
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
1919
import com.datadog.android.internal.telemetry.InternalTelemetryEvent
2020
import com.datadog.android.internal.utils.loggableStackTrace
21-
import com.datadog.android.rum.GlobalRumMonitor
2221
import com.datadog.android.rum.RumActionType
2322
import com.datadog.android.rum.RumAttributes
2423
import com.datadog.android.rum.RumPerformanceMetric
@@ -77,9 +76,9 @@ internal open class RumViewScope(
7776

7877
internal val url = key.url.replace('.', '/')
7978

80-
internal val eventAttributes: MutableMap<String, Any?> = initialAttributes.toMutableMap()
81-
private var globalAttributes: Map<String, Any?> = resolveGlobalAttributes(sdkCore)
79+
internal val viewAttributes: MutableMap<String, Any?> = initialAttributes.toMutableMap()
8280
private val internalAttributes: MutableMap<String, Any?> = mutableMapOf()
81+
private var memoizedParentAttributes: Map<String, Any?> = emptyMap()
8382

8483
private var sessionId: String = parentScope.getRumContext().sessionId
8584
internal var viewId: String = UUID.randomUUID().toString()
@@ -187,7 +186,6 @@ internal open class RumViewScope(
187186
event: RumRawEvent,
188187
writer: DataWriter<Any>
189188
): RumScope? {
190-
updateGlobalAttributes(sdkCore, event)
191189
when (event) {
192190
is RumRawEvent.ResourceSent -> onResourceSent(event, writer)
193191
is RumRawEvent.ActionSent -> onActionSent(event, writer)
@@ -252,6 +250,14 @@ internal open class RumViewScope(
252250
)
253251
}
254252

253+
override fun getCustomAttributes(): Map<String, Any?> {
254+
return if (!stopped) {
255+
parentScope.getCustomAttributes() + viewAttributes
256+
} else {
257+
memoizedParentAttributes + viewAttributes
258+
}
259+
}
260+
255261
override fun isActive(): Boolean {
256262
return !stopped
257263
}
@@ -365,7 +371,8 @@ internal open class RumViewScope(
365371
)
366372
}
367373
}
368-
eventAttributes.putAll(event.attributes)
374+
viewAttributes.putAll(event.attributes)
375+
memoizedParentAttributes = parentScope.getCustomAttributes().toMap()
369376
}
370377
}
371378
}
@@ -427,13 +434,10 @@ internal open class RumViewScope(
427434
delegateEventToChildren(event, writer)
428435
if (stopped) return
429436

430-
val updatedEvent = event.copy(
431-
attributes = addExtraAttributes(event.attributes)
432-
)
433437
activeResourceScopes[event.key] = RumResourceScope.fromEvent(
434438
this,
435439
sdkCore,
436-
updatedEvent,
440+
event,
437441
firstPartyHostHeaderTypeResolver,
438442
serverTimeOffsetInMs,
439443
featuresContextResolver,
@@ -454,10 +458,11 @@ internal open class RumViewScope(
454458

455459
val rumContext = getRumContext()
456460

457-
val updatedAttributes = addExtraAttributes(event.attributes)
458-
val isFatal = updatedAttributes
459-
.remove(RumAttributes.INTERNAL_ERROR_IS_CRASH) as? Boolean == true || event.isFatal
460-
val errorFingerprint = updatedAttributes.remove(RumAttributes.ERROR_FINGERPRINT) as? String
461+
val errorCustomAttributes = getCustomAttributes().toMutableMap()
462+
errorCustomAttributes.putAll(event.attributes)
463+
val isFatal = errorCustomAttributes.remove(RumAttributes.INTERNAL_ERROR_IS_CRASH) as? Boolean == true ||
464+
event.isFatal
465+
val errorFingerprint = errorCustomAttributes.remove(RumAttributes.ERROR_FINGERPRINT) as? String
461466
// if a cross-platform crash was already reported, do not send its native version
462467
if (crashCount > 0 && isFatal) return
463468

@@ -559,7 +564,7 @@ internal open class RumViewScope(
559564
brand = datadogContext.deviceInfo.deviceBrand,
560565
architecture = datadogContext.deviceInfo.architecture
561566
),
562-
context = ErrorEvent.Context(additionalProperties = updatedAttributes),
567+
context = ErrorEvent.Context(additionalProperties = errorCustomAttributes),
563568
dd = ErrorEvent.Dd(
564569
session = ErrorEvent.DdSession(
565570
sessionPrecondition = rumContext.sessionStartReason.toErrorSessionPrecondition()
@@ -897,7 +902,7 @@ internal open class RumViewScope(
897902
val isSlowRendered = resolveRefreshRateInfo(refreshRateInfo) ?: false
898903
// make a copy - by the time we iterate over it on another thread, it may already be changed
899904
val eventFeatureFlags = featureFlags.toMutableMap()
900-
val eventAdditionalAttributes = (eventAttributes + globalAttributes).toMutableMap()
905+
val viewCustomAttributes = getCustomAttributes().toMutableMap()
901906
val uiSlownessReport = slowFramesListener?.resolveReport(viewId, viewComplete, durationNs)
902907
val slowFrames = uiSlownessReport?.slowFramesRecords?.map {
903908
ViewEvent.SlowFrame(
@@ -957,7 +962,6 @@ internal open class RumViewScope(
957962
} else {
958963
ViewEvent.ViewEventSessionType.SYNTHETICS
959964
}
960-
961965
ViewEvent(
962966
date = eventTimestamp,
963967
featureFlags = ViewEvent.Context(additionalProperties = eventFeatureFlags),
@@ -1032,7 +1036,7 @@ internal open class RumViewScope(
10321036
brand = datadogContext.deviceInfo.deviceBrand,
10331037
architecture = datadogContext.deviceInfo.architecture
10341038
),
1035-
context = ViewEvent.Context(additionalProperties = eventAdditionalAttributes),
1039+
context = ViewEvent.Context(additionalProperties = viewCustomAttributes),
10361040
dd = ViewEvent.Dd(
10371041
documentVersion = eventVersion,
10381042
session = ViewEvent.DdSession(
@@ -1050,16 +1054,6 @@ internal open class RumViewScope(
10501054
}.submit()
10511055
}
10521056

1053-
private fun updateGlobalAttributes(sdkCore: InternalSdkCore, event: RumRawEvent) {
1054-
if (!stopped && event !is RumRawEvent.StartView) {
1055-
globalAttributes = resolveGlobalAttributes(sdkCore)
1056-
}
1057-
}
1058-
1059-
private fun resolveGlobalAttributes(sdkCore: InternalSdkCore): Map<String, Any?> {
1060-
return GlobalRumMonitor.get(sdkCore).getAttributes().toMap()
1061-
}
1062-
10631057
private fun resolveViewDuration(event: RumRawEvent) {
10641058
stoppedNanos = event.eventTime.nanoTime
10651059
val duration = stoppedNanos - startedNanos
@@ -1114,12 +1108,6 @@ internal open class RumViewScope(
11141108
null
11151109
}
11161110

1117-
private fun addExtraAttributes(
1118-
attributes: Map<String, Any?>
1119-
): MutableMap<String, Any?> {
1120-
return attributes.toMutableMap().apply { putAll(globalAttributes) }
1121-
}
1122-
11231111
@Suppress("LongMethod")
11241112
@WorkerThread
11251113
private fun onApplicationStarted(
@@ -1128,7 +1116,7 @@ internal open class RumViewScope(
11281116
) {
11291117
pendingActionCount++
11301118
val rumContext = getRumContext()
1131-
val localCopyOfGlobalAttributes = globalAttributes.toMutableMap()
1119+
val actionCustomAttributes = getCustomAttributes().toMutableMap()
11321120
sdkCore.newRumEventWriteOperation(writer) { datadogContext ->
11331121
val user = datadogContext.userInfo
11341122
val syntheticsAttribute = if (
@@ -1199,7 +1187,7 @@ internal open class RumViewScope(
11991187
architecture = datadogContext.deviceInfo.architecture
12001188
),
12011189
context = ActionEvent.Context(
1202-
additionalProperties = localCopyOfGlobalAttributes
1190+
additionalProperties = actionCustomAttributes
12031191
),
12041192
dd = ActionEvent.Dd(
12051193
session = ActionEvent.DdSession(
@@ -1231,9 +1219,10 @@ internal open class RumViewScope(
12311219
if (stopped) return
12321220

12331221
val rumContext = getRumContext()
1234-
val updatedAttributes = addExtraAttributes(
1235-
mapOf(RumAttributes.LONG_TASK_TARGET to event.target)
1236-
)
1222+
val longTaskCustomAttributes = getCustomAttributes().toMutableMap().apply {
1223+
put(RumAttributes.LONG_TASK_TARGET, event.target)
1224+
}
1225+
12371226
val timestamp = event.eventTime.timestamp + serverTimeOffsetInMs
12381227
val isFrozenFrame = event.durationNs > FROZEN_FRAME_THRESHOLD_NS
12391228
slowFramesListener?.onAddLongTask(event.durationNs)
@@ -1307,7 +1296,7 @@ internal open class RumViewScope(
13071296
brand = datadogContext.deviceInfo.deviceBrand,
13081297
architecture = datadogContext.deviceInfo.architecture
13091298
),
1310-
context = LongTaskEvent.Context(additionalProperties = updatedAttributes),
1299+
context = LongTaskEvent.Context(additionalProperties = longTaskCustomAttributes),
13111300
dd = LongTaskEvent.Dd(
13121301
session = LongTaskEvent.DdSession(
13131302
sessionPrecondition = rumContext.sessionStartReason.toLongTaskSessionPrecondition()
@@ -1367,7 +1356,7 @@ internal open class RumViewScope(
13671356
viewChangedListener?.onViewChanged(
13681357
RumViewInfo(
13691358
key = key,
1370-
attributes = eventAttributes,
1359+
attributes = viewAttributes,
13711360
isActive = isActive()
13721361
)
13731362
)

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScopeTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ internal class RumApplicationScopeTest {
313313
val viewScope = viewManager.childrenScopes.first()
314314
check(viewScope is RumViewScope)
315315
assertThat(viewScope.key).isEqualTo(fakeKey)
316-
assertThat(viewScope.eventAttributes).isEqualTo(mockAttributes)
316+
assertThat(viewScope.viewAttributes).isEqualTo(mockAttributes)
317317
}
318318

319319
@Test

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/domain/scope/RumViewManagerScopeTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ internal class RumViewManagerScopeTest {
244244
.isEqualTo(resolveExpectedTimestamp(fakeEvent.eventTime.timestamp))
245245
assertThat(it.key).isEqualTo(fakeEvent.key)
246246
assertThat(it.type).isEqualTo(RumViewType.FOREGROUND)
247-
assertThat(it.eventAttributes).containsAllEntriesOf(fakeEvent.attributes)
247+
assertThat(it.viewAttributes).containsAllEntriesOf(fakeEvent.attributes)
248248
assertThat(it.firstPartyHostHeaderTypeResolver).isSameAs(mockResolver)
249249
assertThat(it.version).isEqualTo(2)
250250
}
@@ -271,7 +271,7 @@ internal class RumViewManagerScopeTest {
271271
.isEqualTo(resolveExpectedTimestamp(fakeEvent.eventTime.timestamp))
272272
assertThat(it.key).isEqualTo(fakeEvent.key)
273273
assertThat(it.type).isEqualTo(RumViewType.FOREGROUND)
274-
assertThat(it.eventAttributes).containsAllEntriesOf(fakeEvent.attributes)
274+
assertThat(it.viewAttributes).containsAllEntriesOf(fakeEvent.attributes)
275275
assertThat(it.firstPartyHostHeaderTypeResolver).isSameAs(mockResolver)
276276
assertThat(it.version).isEqualTo(2)
277277
}

0 commit comments

Comments
 (0)