Closed shubhamguptadream11 closed 8 months ago
While this isn't something we fully support yet, you should be able to achieve cross-layer linking by passing the spanId
and traceId
from Android to ReactNative. You can create ReactNative spans that are children of an Android span using:
BugsnagPerformance.startSpan('Custom span', {
parentContext: {id: parentSpanId, traceId, isValid: () => true},
})
and you can retrieve the current context on the Android side using:
val ctx = SpanContext.current
val traceId: UUID = ctx.traceId
val spanId: Long = ctx.spanId
The traceId
and spanId
will need to be hex encoded for the JavaScript layer.
@lemnik Will try this and let you know. Thanks!
@lemnik Hey above solution worked. But I am getting this on first RN span.
This span’s parent does not exist in the trace.
Attaching the screenshot for this. Here rn-app-launch
is the first point which is taking traceId and spanId from android.
The parentSpanId
of the rn-app-launch
span is not attached to any span in the trace. I expect you'll be able to fix this by double-checking which ids you are sending. If you continue to have problems please contact support at support@bugsnag.com.
It's also important that the span (the parent of rn-app-launch
) is end()
ed by whichever layer created it (in this case Android). Spans are not reported unless they are ended.
Hey, I am passing traceId and spanId from android itself. Then starting a span in react-native environment. By doing this
const span = BugsnagPerformance.startSpan('rn-app-launch', {
parentContext: {
traceId: uuidToHex(traceId),
id: spanId,
isValid: () => true,
},
});
someHeavyOperation(); // Here I am starting a new span in rn world as well with name rn-heavy-operation and ending it inside that function only.
span.end();
Then making a bridge call after this to end android span as well.
I think there is something wrong in Ids. From android I am passing these ids: traceId: 1d8a320b-db58-4f96-979e-e3d88e759c04 spanId: 9108058140016896339
In RN world I am receiving exactly same thing.
traceId: 1d8a320bdb584f96979ee3d88e759c04
spanId: 9108058140016896339
I intercepted the trace which is being exported in RN World as well Here is the logs for this
{
"resourceSpans": [
{
"resource": {
"attributes": [
{
"key": "deployment.environment",
"value": {
"stringValue": "production"
}
},
{
"key": "telemetry.sdk.name",
"value": {
"stringValue": "bugsnag.performance.reactnative"
}
},
{
"key": "telemetry.sdk.version",
"value": {
"stringValue": "2.2.0"
}
},
{
"key": "os.type",
"value": {
"stringValue": "linux"
}
},
{
"key": "os.name",
"value": {
"stringValue": "android"
}
},
{
"key": "bugsnag.app.platform",
"value": {
"stringValue": "android"
}
},
{
"key": "os.version",
"value": {
"stringValue": "11"
}
},
{
"key": "bugsnag.device.android_api_version",
"value": {
"stringValue": "30"
}
},
{
"key": "host.arch",
"value": {
"stringValue": "arm64"
}
},
{
"key": "bugsnag.app.version_code",
"value": {
"stringValue": "1"
}
},
{
"key": "device.model.identifier",
"value": {
"stringValue": "LE2111"
}
},
{
"key": "service.name",
"value": {
"stringValue": "com.dream11otel"
}
},
{
"key": "device.manufacturer",
"value": {
"stringValue": "OnePlus"
}
},
{
"key": "device.id",
"value": {
"stringValue": "7eb2ab6b-cbf0-4f8b-a0b2-3182a8c95177"
}
}
]
},
"scopeSpans": [
{
"spans": [
{
"name": "[AppStart/ReactNativeInit]",
"kind": 3,
"spanId": "9ca6502fc2025860",
"traceId": "16460fa04b6eb7a761275ed785ba6711",
"startTimeUnixNano": "1710325361728022000",
"endTimeUnixNano": "1710325362350212900",
"attributes": [
{
"key": "bugsnag.span.category",
"value": {
"stringValue": "app_start"
}
},
{
"key": "bugsnag.app_start.type",
"value": {
"stringValue": "ReactNativeInit"
}
},
{
"key": "net.host.connection.type",
"value": {
"stringValue": "unknown"
}
},
{
"key": "bugsnag.sampling.p",
"value": {
"doubleValue": 1
}
}
],
"events": []
},
{
"name": "rn-heavy-operation",
"kind": 3,
"spanId": "a5cda220235345e0",
"traceId": "1d8a320bdb584f96979ee3d88e759c04",
"parentSpanId": "e4d39bd4e62f3bea",
"startTimeUnixNano": "1710325362387342300",
"endTimeUnixNano": "1710325398999003000",
"attributes": [
{
"key": "bugsnag.span.first_class",
"value": {
"boolValue": false
}
},
{
"key": "bugsnag.span.category",
"value": {
"stringValue": "custom"
}
},
{
"key": "net.host.connection.type",
"value": {
"stringValue": "wifi"
}
},
{
"key": "bugsnag.sampling.p",
"value": {
"doubleValue": 1
}
}
],
"events": []
},
{
"name": "rn-app-launch",
"kind": 3,
"spanId": "e4d39bd4e62f3bea",
"traceId": "1d8a320bdb584f96979ee3d88e759c04",
"parentSpanId": "9108058140016896339",
"startTimeUnixNano": "1710325362386789400",
"endTimeUnixNano": "1710325398999296500",
"attributes": [
{
"key": "bugsnag.span.category",
"value": {
"stringValue": "custom"
}
},
{
"key": "net.host.connection.type",
"value": {
"stringValue": "wifi"
}
},
{
"key": "bugsnag.sampling.p",
"value": {
"doubleValue": 1
}
}
],
"events": []
}
]
}
]
}
]
}
If you see in above logs. Then for rn-app-launch
span parentSpanId is correctly attached and this is same as what I sent from android side and I ended this span as well.
The only thing I noticed different here is the format of spanId. I mean if we see rn-heavy-operation
parentSpanId then its format is e4d39bd4e62f3bea
(hex format) which is being generated on RN world itself and linked to rn-app-launch
correctly.
But if we see rn-app-launch
parentSpanId its coming from android world and its format is 9108058140016896339
(Long format).
I checked all other things starting and ending properly.
I'm guessing that the spanId
in the above snippet was directly captured as a Long
on the Android side, and sent over to JS as a number
. In which case the encoding will be incorrect. The spanId
is a 64bit value, and we store it as a string
in the JS layer for convenience and easy debugging. The encoding code used by the Android layer is here, and you can see that when an Android span is serialized to json the value is hex encoded.
Okay do we have any utility function exposed to do this android side?
This worked. I used .toHexString functions before passing it to RN world. Thanks!! @lemnik
Description
Generally if we talk about app Launch in any react native app, its basically the
onCreate
of Main Application to first meaningful paint on react native screen. So in order to track this we need to somehow start a span ononCreate
of serializable and then we need to link some span in RN world to know what's going on in there. And finally after first meaningful paint we overrideonDraw
function to end the android span. To get a better insights all these should be linked with same traceID.Describe the solution you'd like There should be a mechanism to pass traceId and spanId across platforms to link them together. Since span is not serializable so we cannot pass this.
Describe alternatives you've considered I tried passing spanID and traceId by making a bridge call and tried linking this in RN world. But its not working.