Skip to content

Commit 887fd1d

Browse files
authored
Merge pull request #2654 from DataDog/xgouchet/RUM-9908/align_attribute_propagation
RUM-9908 Align attribute propagation mechanism
2 parents 67598c9 + 11b287e commit 887fd1d

19 files changed

+1972
-1178
lines changed

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ package com.datadog.android.rum.internal.domain.scope
99
import androidx.annotation.WorkerThread
1010
import com.datadog.android.api.storage.DataWriter
1111
import com.datadog.android.core.InternalSdkCore
12-
import com.datadog.android.rum.GlobalRumMonitor
1312
import com.datadog.android.rum.RumActionType
1413
import com.datadog.android.rum.internal.FeaturesContextResolver
1514
import com.datadog.android.rum.internal.domain.RumContext
@@ -24,7 +23,7 @@ import java.util.concurrent.TimeUnit
2423
import kotlin.math.max
2524

2625
internal class RumActionScope(
27-
val parentScope: RumScope,
26+
override val parentScope: RumScope,
2827
private val sdkCore: InternalSdkCore,
2928
val waitForStop: Boolean,
3029
eventTime: Time,
@@ -51,9 +50,7 @@ internal class RumActionScope(
5150
private var lastInteractionNanos: Long = startedNanos
5251
private val networkInfo = sdkCore.networkInfo
5352

54-
internal val attributes: MutableMap<String, Any?> = initialAttributes.toMutableMap().apply {
55-
putAll(GlobalRumMonitor.get(sdkCore).getAttributes())
56-
}
53+
internal val actionAttributes: MutableMap<String, Any?> = initialAttributes.toMutableMap()
5754

5855
private val ongoingResourceKeys = mutableListOf<WeakReference<Any>>()
5956

@@ -99,6 +96,10 @@ internal class RumActionScope(
9996
return parentScope.getRumContext()
10097
}
10198

99+
override fun getCustomAttributes(): Map<String, Any?> {
100+
return parentScope.getCustomAttributes() + actionAttributes
101+
}
102+
102103
override fun isActive(): Boolean {
103104
return !stopped
104105
}
@@ -141,7 +142,7 @@ internal class RumActionScope(
141142
) {
142143
event.type?.let { type = it }
143144
event.name?.let { name = it }
144-
attributes.putAll(event.attributes)
145+
actionAttributes.putAll(event.attributes)
145146
stopped = true
146147
stoppedNanos = now
147148
lastInteractionNanos = now
@@ -205,8 +206,6 @@ internal class RumActionScope(
205206
if (sent) return
206207

207208
val actualType = type
208-
attributes.putAll(GlobalRumMonitor.get(sdkCore).getAttributes())
209-
val eventAttributes = attributes.toMutableMap()
210209
val rumContext = getRumContext()
211210

212211
// make a copy so that closure captures at the state as of now
@@ -303,7 +302,7 @@ internal class RumActionScope(
303302
brand = datadogContext.deviceInfo.deviceBrand,
304303
architecture = datadogContext.deviceInfo.architecture
305304
),
306-
context = ActionEvent.Context(additionalProperties = eventAttributes),
305+
context = ActionEvent.Context(additionalProperties = getCustomAttributes().toMutableMap()),
307306
dd = ActionEvent.Dd(
308307
session = ActionEvent.DdSession(
309308
sessionPrecondition = rumContext.sessionStartReason.toActionSessionPrecondition()

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import com.datadog.android.api.storage.DataWriter
1414
import com.datadog.android.core.InternalSdkCore
1515
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
1616
import com.datadog.android.rum.DdRumContentProvider
17+
import com.datadog.android.rum.GlobalRumMonitor
1718
import com.datadog.android.rum.RumSessionListener
1819
import com.datadog.android.rum.internal.domain.RumContext
1920
import com.datadog.android.rum.internal.domain.Time
@@ -42,6 +43,8 @@ internal class RumApplicationScope(
4243
private val slowFramesListener: SlowFramesListener?
4344
) : RumScope, RumViewChangedListener {
4445

46+
override val parentScope: RumScope? = null
47+
4548
private var rumContext = RumContext(applicationId = applicationId)
4649

4750
internal val childScopes: MutableList<RumScope> = mutableListOf(
@@ -113,6 +116,10 @@ internal class RumApplicationScope(
113116
return rumContext
114117
}
115118

119+
override fun getCustomAttributes(): Map<String, Any?> {
120+
return GlobalRumMonitor.get(sdkCore).getAttributes()
121+
}
122+
116123
// endregion
117124

118125
override fun onViewChanged(viewInfo: RumViewInfo) {

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

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import com.datadog.android.api.storage.DataWriter
1212
import com.datadog.android.core.InternalSdkCore
1313
import com.datadog.android.core.internal.net.FirstPartyHostHeaderTypeResolver
1414
import com.datadog.android.internal.utils.loggableStackTrace
15-
import com.datadog.android.rum.GlobalRumMonitor
1615
import com.datadog.android.rum.RumAttributes
1716
import com.datadog.android.rum.RumErrorSource
1817
import com.datadog.android.rum.RumResourceKind
@@ -35,7 +34,7 @@ import java.util.UUID
3534

3635
@Suppress("LongParameterList", "TooManyFunctions")
3736
internal class RumResourceScope(
38-
internal val parentScope: RumScope,
37+
override val parentScope: RumScope,
3938
internal val sdkCore: InternalSdkCore,
4039
internal val url: String,
4140
internal val method: RumResourceMethod,
@@ -50,9 +49,8 @@ internal class RumResourceScope(
5049
) : RumScope {
5150

5251
internal val resourceId: String = UUID.randomUUID().toString()
53-
internal val attributes: MutableMap<String, Any?> = initialAttributes.toMutableMap().apply {
54-
putAll(GlobalRumMonitor.get(sdkCore).getAttributes())
55-
}
52+
internal val resourceAttributes: MutableMap<String, Any?> = initialAttributes.toMutableMap()
53+
5654
private var timing: ResourceTiming? = null
5755
private val initialContext = parentScope.getRumContext()
5856

@@ -95,6 +93,10 @@ internal class RumResourceScope(
9593
return initialContext
9694
}
9795

96+
override fun getCustomAttributes(): Map<String, Any?> {
97+
return parentScope.getCustomAttributes() + resourceAttributes
98+
}
99+
98100
override fun isActive(): Boolean {
99101
return !stopped
100102
}
@@ -110,7 +112,7 @@ internal class RumResourceScope(
110112
) {
111113
if (key != event.key) return
112114
stopped = true
113-
attributes.putAll(event.attributes)
115+
resourceAttributes.putAll(event.attributes)
114116
kind = event.kind
115117
statusCode = event.statusCode
116118
size = event.size
@@ -138,7 +140,7 @@ internal class RumResourceScope(
138140
writer: DataWriter<Any>
139141
) {
140142
if (key != event.key) return
141-
attributes.putAll(event.attributes)
143+
resourceAttributes.putAll(event.attributes)
142144
sendError(
143145
event.message,
144146
event.source,
@@ -157,7 +159,7 @@ internal class RumResourceScope(
157159
writer: DataWriter<Any>
158160
) {
159161
if (key != event.key) return
160-
attributes.putAll(event.attributes)
162+
resourceAttributes.putAll(event.attributes)
161163

162164
val errorCategory =
163165
if (event.stackTrace.isNotEmpty()) ErrorEvent.Category.EXCEPTION else null
@@ -182,10 +184,9 @@ internal class RumResourceScope(
182184
eventTime: Time,
183185
writer: DataWriter<Any>
184186
) {
185-
attributes.putAll(GlobalRumMonitor.get(sdkCore).getAttributes())
186-
val traceId = attributes.remove(RumAttributes.TRACE_ID)?.toString()
187-
val spanId = attributes.remove(RumAttributes.SPAN_ID)?.toString()
188-
val rulePsr = attributes.remove(RumAttributes.RULE_PSR) as? Number
187+
val traceId = resourceAttributes.remove(RumAttributes.TRACE_ID)?.toString()
188+
val spanId = resourceAttributes.remove(RumAttributes.SPAN_ID)?.toString()
189+
val rulePsr = resourceAttributes.remove(RumAttributes.RULE_PSR) as? Number
189190

190191
val rumContext = getRumContext()
191192
val syntheticsAttribute = if (
@@ -207,15 +208,14 @@ internal class RumResourceScope(
207208

208209
@Suppress("UNCHECKED_CAST")
209210
val finalTiming = timing ?: extractResourceTiming(
210-
attributes.remove(RumAttributes.RESOURCE_TIMINGS) as? Map<String, Any?>
211+
resourceAttributes.remove(RumAttributes.RESOURCE_TIMINGS) as? Map<String, Any?>
211212
)
212213
val graphql = resolveGraphQLAttributes(
213-
attributes.remove(RumAttributes.GRAPHQL_OPERATION_TYPE) as? String?,
214-
attributes.remove(RumAttributes.GRAPHQL_OPERATION_NAME) as? String?,
215-
attributes.remove(RumAttributes.GRAPHQL_PAYLOAD) as? String?,
216-
attributes.remove(RumAttributes.GRAPHQL_VARIABLES) as? String?
214+
resourceAttributes.remove(RumAttributes.GRAPHQL_OPERATION_TYPE) as? String?,
215+
resourceAttributes.remove(RumAttributes.GRAPHQL_OPERATION_NAME) as? String?,
216+
resourceAttributes.remove(RumAttributes.GRAPHQL_PAYLOAD) as? String?,
217+
resourceAttributes.remove(RumAttributes.GRAPHQL_VARIABLES) as? String?
217218
)
218-
val eventAttributes = attributes.toMutableMap()
219219
sdkCore.newRumEventWriteOperation(writer) { datadogContext ->
220220
val user = datadogContext.userInfo
221221
val hasReplay = featuresContextResolver.resolveViewHasReplay(
@@ -282,7 +282,7 @@ internal class RumResourceScope(
282282
brand = datadogContext.deviceInfo.deviceBrand,
283283
architecture = datadogContext.deviceInfo.architecture
284284
),
285-
context = ResourceEvent.Context(additionalProperties = eventAttributes),
285+
context = ResourceEvent.Context(additionalProperties = getCustomAttributes().toMutableMap()),
286286
dd = ResourceEvent.Dd(
287287
traceId = traceId,
288288
spanId = spanId,
@@ -343,12 +343,9 @@ internal class RumResourceScope(
343343
writer: DataWriter<Any>,
344344
resourceStopTimestampInNanos: Long
345345
) {
346-
attributes.putAll(GlobalRumMonitor.get(sdkCore).getAttributes())
347-
val errorFingerprint = attributes.remove(RumAttributes.ERROR_FINGERPRINT) as? String
348-
346+
val errorFingerprint = resourceAttributes.remove(RumAttributes.ERROR_FINGERPRINT) as? String
349347
val rumContext = getRumContext()
350348

351-
val eventAttributes = attributes.toMutableMap()
352349
val syntheticsAttribute = if (
353350
rumContext.syntheticsTestId.isNullOrBlank() ||
354351
rumContext.syntheticsResultId.isNullOrBlank()
@@ -431,7 +428,7 @@ internal class RumResourceScope(
431428
brand = datadogContext.deviceInfo.deviceBrand,
432429
architecture = datadogContext.deviceInfo.architecture
433430
),
434-
context = ErrorEvent.Context(additionalProperties = eventAttributes),
431+
context = ErrorEvent.Context(additionalProperties = getCustomAttributes().toMutableMap()),
435432
dd = ErrorEvent.Dd(
436433
session = ErrorEvent.DdSession(
437434
sessionPrecondition = rumContext.sessionStartReason.toErrorSessionPrecondition()

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ package com.datadog.android.rum.internal.domain.scope
99
import androidx.annotation.WorkerThread
1010
import com.datadog.android.api.storage.DataWriter
1111
import com.datadog.android.rum.internal.domain.RumContext
12-
import com.datadog.tools.annotation.NoOpImplementation
1312

14-
@NoOpImplementation
1513
internal interface RumScope {
1614

15+
val parentScope: RumScope?
16+
1717
/**
1818
* Handles an incoming event.
1919
* If needed, writes a RumEvent to the provided writer.
@@ -37,6 +37,15 @@ internal interface RumScope {
3737
*/
3838
fun getRumContext(): RumContext
3939

40+
/**
41+
* @return the custom attributes for this scope (including the parent's scope current attributes)
42+
* A given scope's attribute can override a parent scope's attribute.
43+
*/
44+
fun getCustomAttributes(): Map<String, Any?> {
45+
// Default implementation, simply returns the parent's attributes
46+
return parentScope?.getCustomAttributes() ?: emptyMap()
47+
}
48+
4049
companion object {
4150
internal const val SYNTHETICS_LOGCAT_TAG = "DatadogSynthetics"
4251
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicLong
2727

2828
@Suppress("LongParameterList")
2929
internal class RumSessionScope(
30-
private val parentScope: RumScope,
30+
override val parentScope: RumScope,
3131
private val sdkCore: InternalSdkCore,
3232
private val sessionEndedMetricDispatcher: SessionMetricDispatcher,
3333
internal val sampleRate: Float,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import java.util.concurrent.TimeUnit
3333

3434
@Suppress("LongParameterList")
3535
internal class RumViewManagerScope(
36-
private val parentScope: RumScope,
36+
override val parentScope: RumScope,
3737
private val sdkCore: InternalSdkCore,
3838
private val sessionEndedMetricDispatcher: SessionMetricDispatcher,
3939
private val backgroundTrackingEnabled: Boolean,

0 commit comments

Comments
 (0)