Skip to content

Commit a2821ef

Browse files
committed
Add OTel resource attributes to the embrace payload envelopes
1 parent 2f46115 commit a2821ef

File tree

8 files changed

+37
-11
lines changed

8 files changed

+37
-11
lines changed

embrace-android-core/src/main/kotlin/io/embrace/android/embracesdk/internal/injection/PayloadSourceModuleImpl.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ class PayloadSourceModuleImpl(
109109
AppEnvironment(isDebug)
110110
}
111111

112+
private val otelResourceAttributes: Map<String, String> by lazy {
113+
otelModule.otelSdkConfig.getOTelResourceAttributes()
114+
}
115+
112116
override val resourceSource: EnvelopeResourceSource by singleton {
113117
EmbTrace.trace("resource-source") {
114118
EnvelopeResourceSourceImpl(
@@ -126,8 +130,10 @@ class PayloadSourceModuleImpl(
126130
},
127131
rnBundleIdProvider = { rnBundleIdTracker.getReactNativeBundleId() },
128132
versionName = BuildConfig.VERSION_NAME,
129-
versionCode = BuildConfig.VERSION_CODE.toIntOrNull()
130-
)
133+
versionCode = BuildConfig.VERSION_CODE.toIntOrNull(),
134+
) {
135+
otelResourceAttributes
136+
}
131137
}
132138
}
133139

embrace-android-core/src/test/kotlin/io/embrace/android/embracesdk/internal/envelope/resource/EnvelopeResourceSourceImplTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ internal class EnvelopeResourceSourceImplTest {
4646
"",
4747
53,
4848
{ "fakeReactNativeBundleId" }
49-
)
49+
) {
50+
mapOf("resource-attr" to "foo")
51+
}
5052
val envelope = source.getEnvelopeResource()
5153

5254
assertEquals("2.5.1", envelope.appVersion)
@@ -73,5 +75,6 @@ internal class EnvelopeResourceSourceImplTest {
7375
assertEquals("26", envelope.osCode)
7476
assertEquals("1920x1080", envelope.screenResolution)
7577
assertEquals(8, envelope.numCores)
78+
assertEquals("foo", envelope.extras["resource-attr"])
7679
}
7780
}

embrace-android-envelope/src/main/kotlin/io/embrace/android/embracesdk/internal/envelope/resource/EnvelopeResourceSourceImpl.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import io.embrace.android.embracesdk.internal.capture.metadata.AppEnvironment
44
import io.embrace.android.embracesdk.internal.config.ConfigService
55
import io.embrace.android.embracesdk.internal.envelope.metadata.HostedSdkVersionInfo
66
import io.embrace.android.embracesdk.internal.payload.EnvelopeResource
7+
import io.embrace.android.embracesdk.internal.utils.Provider
78
import java.util.concurrent.ConcurrentHashMap
89

910
class EnvelopeResourceSourceImpl(
@@ -14,6 +15,7 @@ class EnvelopeResourceSourceImpl(
1415
private val versionName: String,
1516
private val versionCode: Int?,
1617
private val rnBundleIdProvider: () -> String?,
18+
private val otelResourceAttributesSupplier: Provider<Map<String, String>>,
1719
) : EnvelopeResourceSource {
1820

1921
private val extras = ConcurrentHashMap<String, String>()
@@ -48,7 +50,7 @@ class EnvelopeResourceSourceImpl(
4850
osCode = device.systemInfo.androidOsApiLevel,
4951
screenResolution = device.screenResolution,
5052
numCores = device.numberOfCores,
51-
extras = extras.toMap()
53+
extras = extras.toMap() + otelResourceAttributesSupplier()
5254
)
5355
}
5456

embrace-android-otel/src/main/kotlin/io/embrace/android/embracesdk/internal/otel/config/OtelSdkConfig.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.embrace.android.embracesdk.internal.otel.config
22

33
import io.embrace.android.embracesdk.internal.SystemInfo
4+
import io.embrace.android.embracesdk.internal.otel.impl.EmbMutableAttributeContainer
45
import io.embrace.android.embracesdk.internal.otel.logs.DefaultLogRecordExporter
56
import io.embrace.android.embracesdk.internal.otel.logs.DefaultLogRecordProcessor
67
import io.embrace.android.embracesdk.internal.otel.logs.LogSink
@@ -118,4 +119,10 @@ class OtelSdkConfig(
118119
fun setResourceAttribute(key: String, value: String) {
119120
customAttributes[key] = value
120121
}
122+
123+
fun getOTelResourceAttributes(): Map<String, String> {
124+
val resourceAttrContainer = EmbMutableAttributeContainer()
125+
resourceAction(resourceAttrContainer)
126+
return resourceAttrContainer.attributes
127+
}
121128
}

embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/EmbraceInternalInterfaceTest.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,11 @@ internal class EmbraceInternalInterfaceTest {
5858
}
5959
},
6060
assertAction = {
61-
val expected = mapOf("foo" to "bar")
6261
val sessionResource = checkNotNull(getSingleSessionEnvelope().resource)
63-
assertEquals(expected, sessionResource.extras)
62+
assertEquals("bar", sessionResource.extras["foo"])
6463

6564
val logResource = checkNotNull(getSingleLogEnvelope().resource)
66-
assertEquals(expected, logResource.extras)
65+
assertEquals("bar", logResource.extras["foo"])
6766
}
6867
)
6968
}

embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/session/SessionPayloadTest.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ internal class SessionPayloadTest {
1717
val testRule: SdkIntegrationTestRule = SdkIntegrationTestRule()
1818

1919
@Test
20-
fun `device and app attributes are present in session envelope`() {
20+
fun `device, app, and otel resource attributes are present in session envelope`() {
2121
testRule.runTest(
22+
preSdkStartAction = {
23+
embrace.setResourceAttribute("resource-attr", "foo")
24+
},
2225
testCaseAction = {
2326
recordSession()
2427

@@ -33,6 +36,7 @@ internal class SessionPayloadTest {
3336
assertTrue(checkNotNull(osName).isNotBlank())
3437
assertTrue(checkNotNull(deviceModel).isNotBlank())
3538
assertEquals(AppFramework.NATIVE, appFramework)
39+
assertEquals("foo", extras["resource-attr"])
3640
}
3741
assertTrue(getSessionId().isNotBlank())
3842
}

embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testframework/assertions/JsonComparator.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ internal object JsonComparator {
2020
*/
2121
fun compare(expected: JSONObject, observed: JSONObject, path: String = ""): List<String> {
2222
val mismatches = mutableListOf<String>()
23+
var findMissingKeys = true
2324

2425
expected.keys().forEach { key ->
2526
val expectedValue = expected.get(key)
@@ -30,6 +31,7 @@ internal object JsonComparator {
3031
else -> "$path.$key"
3132
}
3233
if (expectedValue == IGNORE_VALUE) {
34+
findMissingKeys = false
3335
return@forEach
3436
}
3537
if (observedValue == null) {
@@ -39,8 +41,10 @@ internal object JsonComparator {
3941
compareJsonValue(expectedValue, observedValue, mismatches, currentPath)
4042
}
4143

42-
// Check for keys in observed JSON that are not present in expected JSON recursively
43-
findMissingExpectedKeys(observed, expected, mismatches)
44+
// Check for keys in observed JSON that are not present in expected JSON recursively only if the parent value isn't ignored
45+
if (findMissingKeys) {
46+
findMissingExpectedKeys(observed, expected, mismatches)
47+
}
4448
return mismatches
4549
}
4650

embrace-android-sdk/src/test/resources/v2_session_expected.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@
3333
"os_version": "__EMBRACE_TEST_IGNORE__",
3434
"os_code": "__EMBRACE_TEST_IGNORE__",
3535
"screen_resolution": "__EMBRACE_TEST_IGNORE__",
36-
"num_cores": "__EMBRACE_TEST_IGNORE__"
36+
"num_cores": "__EMBRACE_TEST_IGNORE__",
37+
"extras": "__EMBRACE_TEST_IGNORE__"
3738
},
3839
"type": "spans",
3940
"version": "0.1.0"

0 commit comments

Comments
 (0)