Skip to content

Commit

Permalink
refactor(react-native): add ReactNativeSpanContext class
Browse files Browse the repository at this point in the history
  • Loading branch information
yousif-bugsnag committed Nov 29, 2024
1 parent dec156d commit 8d55f2c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
package com.bugsnag.reactnative.performance;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.annotation.NonNull;

import androidx.annotation.Nullable;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import java.security.SecureRandom;
import java.util.UUID;
import java.util.concurrent.Callable;

import com.bugsnag.android.performance.BugsnagPerformance;
import com.bugsnag.android.performance.SpanContext;
import com.bugsnag.android.performance.SpanOptions;

import com.bugsnag.android.performance.internal.BugsnagClock;
import com.bugsnag.android.performance.internal.EncodingUtils;
import com.bugsnag.android.performance.internal.SpanFactory;
import com.bugsnag.android.performance.internal.SpanImpl;
import com.bugsnag.android.performance.internal.processing.ImmutableConfig;
import com.bugsnag.reactnative.performance.ReactNativeSpanOptions;

class NativeBugsnagPerformanceImpl {

static final String MODULE_NAME = "BugsnagReactNativePerformance";

private final ReactApplicationContext reactContext;

private final SecureRandom random = new SecureRandom();
Expand Down Expand Up @@ -117,7 +113,7 @@ public WritableMap getNativeConfiguration() {

WritableMap result = Arguments.createMap();
result.putString("apiKey", nativeConfig.getApiKey());
result.putString("endpoint", nativeConfig.getEndpoint());
result.putString("endpoint", nativeConfig.getEndpoint());
result.putString("releaseStage", nativeConfig.getReleaseStage());
result.putString("serviceName", nativeConfig.getServiceName());
result.putInt("attributeCountLimit", nativeConfig.getAttributeCountLimit());
Expand All @@ -141,14 +137,14 @@ public WritableMap getNativeConfiguration() {

return result;
}

@Nullable
public WritableMap startNativeSpan(String name, ReadableMap options) {
if (!isNativePerformanceAvailable) {
return null;
}

SpanOptions spanOptions = jsSpanOptionsToNativeSpanOptions(options);
SpanOptions spanOptions = readableMapToSpanOptions(options);
SpanFactory spanFactory = BugsnagPerformance.INSTANCE.getInstrumentedAppState$internal().getSpanFactory();
SpanImpl nativeSpan = spanFactory.createCustomSpan(name, spanOptions);

Expand All @@ -167,70 +163,39 @@ private WritableMap nativeSpanToJsSpan(SpanImpl nativeSpan) {
long unixNanoStartTime = BugsnagClock.INSTANCE.elapsedNanosToUnixTime(nativeSpan.getStartTime$internal());
span.putDouble("startTime", (double)unixNanoStartTime);

Long parentSpanId = nativeSpan.getParentSpanId();
if (parentSpanId > 0L) {
long parentSpanId = nativeSpan.getParentSpanId();
if (parentSpanId != 0L) {
span.putString("parentSpanId", EncodingUtils.toHexString(parentSpanId));
}

return span;
}

private SpanOptions jsSpanOptionsToNativeSpanOptions(ReadableMap options) {
private SpanOptions readableMapToSpanOptions(ReadableMap jsOptions) {
SpanOptions spanOptions = SpanOptions.DEFAULTS
.setFirstClass(true)
.makeCurrentContext(false)
.within(null);

if (options.hasKey("startTime")) {
double startTime = options.getDouble("startTime");
if (jsOptions.hasKey("startTime")) {
double startTime = jsOptions.getDouble("startTime");
long nativeStartTime = BugsnagClock.INSTANCE.unixNanoTimeToElapsedRealtime((long)startTime);
spanOptions = spanOptions.startTime(nativeStartTime);
}

ReadableMap parentContext = null;
if (options.hasKey("parentContext") && (parentContext = options.getMap("parentContext")) != null) {
SpanContext nativeParentContext = jsSpanContextToNativeSpanContext(parentContext);
if (jsOptions.hasKey("parentContext") && (parentContext = jsOptions.getMap("parentContext")) != null) {
ReactNativeSpanContext nativeParentContext = new ReactNativeSpanContext(
parentContext.getString("id"),
parentContext.getString("traceId")
);

spanOptions = spanOptions.within(nativeParentContext);
}

return spanOptions;
}

private SpanContext jsSpanContextToNativeSpanContext(ReadableMap spanContext) {
String spanId = spanContext.getString("id");
String traceId = spanContext.getString("traceId");

long nativeSpanId = Long.parseUnsignedLong(spanId, 16);
UUID nativeTraceId = new UUID(Long.parseUnsignedLong(traceId.substring(0, 16), 16), Long.parseUnsignedLong(traceId.substring(16), 16));

SpanContext nativeSpanContext = new SpanContext() {
@Override
public long getSpanId() {
return nativeSpanId;
}

@NonNull
@Override
public UUID getTraceId() {
return nativeTraceId;
}

@NonNull
@Override
public Runnable wrap(@NonNull Runnable runnable) {
return null;
}

@NonNull
@Override
public <T> Callable<T> wrap(@NonNull Callable<T> callable) {
return null;
}
};

return nativeSpanContext;
}

@Nullable
private String abiToArchitecture(@Nullable String abi) {
if (abi == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.bugsnag.reactnative.performance;

import androidx.annotation.NonNull;
import com.bugsnag.android.performance.SpanContext;
import java.util.UUID;
import java.util.concurrent.Callable;

class ReactNativeSpanContext implements SpanContext {
private final long nativeSpanId;
private final UUID nativeTraceId;

public ReactNativeSpanContext(String spanId, String traceId) {
nativeSpanId = Long.parseUnsignedLong(spanId, 16);
nativeTraceId = new UUID(
Long.parseUnsignedLong(traceId.substring(0, 16), 16),
Long.parseUnsignedLong(traceId.substring(16), 16)
);
}

@Override
public long getSpanId() {
return nativeSpanId;
}

@NonNull
@Override
public UUID getTraceId() {
return nativeTraceId;
}

@NonNull
@Override
public Runnable wrap(@NonNull Runnable runnable) {
return SpanContext.DefaultImpls.wrap(this, runnable);
}

@NonNull
@Override
public <T> Callable<T> wrap(@NonNull Callable<T> callable) {
return SpanContext.DefaultImpls.wrap(this, callable);
}
}

0 comments on commit 8d55f2c

Please sign in to comment.