Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions packages/core/lib/clock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@ export interface Clock {
// a function to convert a Date object into the format returned by 'now'
convert: (date: Date) => number

// convert the format returned by 'now' to a unix time in nanoseconds
toUnixNanoseconds: (time: number) => number

// convert a unix time in nanoseconds to the format returned by 'now'
fromUnixNanoseconds: (time: number) => number

// convert the format returned by 'now' into a unix timestamp in nanoseconds
toUnixTimestampNanoseconds: (time: number) => string

// convert a unix timestamp in nanoseconds into the format returned by 'now'
fromUnixNanosecondsTimestamp: (timestamp: string) => number
}
7 changes: 3 additions & 4 deletions packages/platforms/browser/lib/clock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,16 @@ function createClock (performance: PerformanceWithOptionalTimeOrigin, background
})

const toUnixNanoseconds = (time: number) => millisecondsToNanoseconds(calculatedTimeOrigin + time)
const fromUnixNanoseconds = (time: number) => nanosecondsToMilliseconds(time) - calculatedTimeOrigin

return {
now: () => performance.now(),
date: () => new Date(calculatedTimeOrigin + performance.now()),
convert: (date) => date.getTime() - calculatedTimeOrigin,
// convert milliseconds since timeOrigin to unix time in nanoseconds
toUnixNanoseconds,
// convert milliseconds since timeOrigin to full timestamp
toUnixTimestampNanoseconds: (time: number) => toUnixNanoseconds(time).toString(),
// convert unix time in nanoseconds back to milliseconds since timeOrigin
fromUnixNanoseconds: (time: number) => nanosecondsToMilliseconds(time) - calculatedTimeOrigin
// convert a unix timestamp in nanoseconds back to milliseconds since timeOrigin
fromUnixNanosecondsTimestamp: (timestamp: string) => fromUnixNanoseconds(parseInt(timestamp))
}
}

Expand Down
49 changes: 0 additions & 49 deletions packages/platforms/browser/tests/clock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,53 +164,4 @@ describe('Browser Clock', () => {
expect(clock.convert(new Date())).toEqual(0)
})
})

describe('clock.toUnixNanoseconds()', () => {
it('converts performance time to unix nanoseconds', () => {
const timeOrigin = new Date('2023-01-02T00:00:00.000Z')
jest.setSystemTime(timeOrigin)

const clock = createClock(new PerformanceFake(), new ControllableBackgroundingListener())

jest.advanceTimersByTime(250)

const performanceTime = clock.now()
const unixNanoseconds = clock.toUnixNanoseconds(performanceTime)

// Expected: timeOrigin + 250ms in nanoseconds
const expectedNanoseconds = (timeOrigin.getTime() + 250) * 1000000
expect(unixNanoseconds).toBe(expectedNanoseconds)
})
})

describe('clock.fromUnixNanoseconds()', () => {
it('converts unix nanoseconds back to performance time', () => {
const timeOrigin = new Date('2023-01-02T00:00:00.000Z')
jest.setSystemTime(timeOrigin)

const clock = createClock(new PerformanceFake(), new ControllableBackgroundingListener())

// Test with a specific unix nanoseconds value 123ms after timeOrigin
const unixNanoseconds = 1672617600123000000 // 2023-01-02T00:00:00.123Z in nanoseconds
const performanceTime = clock.fromUnixNanoseconds(unixNanoseconds)

expect(typeof performanceTime).toBe('number')
expect(performanceTime).toEqual(123) // 123ms after timeOrigin
})

it('is the inverse of toUnixNanoseconds', () => {
const timeOrigin = new Date('2023-01-02T00:00:00.000Z')
jest.setSystemTime(timeOrigin)

const clock = createClock(new PerformanceFake(), new ControllableBackgroundingListener())

jest.advanceTimersByTime(123)

const originalTime = clock.now()
const unixNanoseconds = clock.toUnixNanoseconds(originalTime)
const roundTripTime = clock.fromUnixNanoseconds(unixNanoseconds)

expect(roundTripTime).toBe(originalTime)
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ public NativeBugsnagPerformanceImpl(ReactApplicationContext reactContext) {
try {
BugsnagPerformanceImpl.INSTANCE.getInstrumentedAppState().getConfig$internal();
isNativePerformanceAvailable = true;
}
catch (LinkageError e) {
} catch (LinkageError e) {
// do nothing, Android Performance SDK is not installed or is incompatible
}
}
Expand Down Expand Up @@ -117,12 +116,12 @@ String requestEntropy() {
random.nextBytes(bytes);

StringBuilder hex = new StringBuilder(bytes.length * 2);
for(byte b : bytes) {
int byteValue = ((int)b & 0xff);
if(byteValue < 16) {
hex.append('0');
}
hex.append(Integer.toHexString(byteValue));
for (byte b : bytes) {
int byteValue = ((int) b & 0xff);
if (byteValue < 16) {
hex.append('0');
}
hex.append(Integer.toHexString(byteValue));
}
return hex.toString();
}
Expand Down Expand Up @@ -204,23 +203,23 @@ WritableMap startNativeSpan(String name, ReadableMap options) {
return nativeSpanToJsSpan(nativeSpan);
}

void markNativeSpanEndTime(String spanId, String traceId, double endTime) {
void markNativeSpanEndTime(String spanId, String traceId, String endTime) {
SpanImpl nativeSpan = openSpans.get(spanId + traceId);
if (nativeSpan != null) {
long nativeEndTime = BugsnagClock.INSTANCE.unixNanoTimeToElapsedRealtime((long)endTime);
long nativeEndTime = BugsnagClock.INSTANCE.unixNanoTimeToElapsedRealtime(Long.parseLong(endTime));
nativeSpan.markEndTime$internal(nativeEndTime);
}
}

void endNativeSpan(String spanId, String traceId, double endTime, ReadableMap jsAttributes, Promise promise) {
void endNativeSpan(String spanId, String traceId, String endTime, ReadableMap jsAttributes, Promise promise) {
SpanImpl nativeSpan = openSpans.remove(spanId + traceId);
if (nativeSpan == null) {
promise.resolve(null);
return;
}

ReactNativeSpanAttributes.setAttributesFromReadableMap(nativeSpan.getAttributes(), jsAttributes);
long nativeEndTime = BugsnagClock.INSTANCE.unixNanoTimeToElapsedRealtime((long)endTime);
long nativeEndTime = BugsnagClock.INSTANCE.unixNanoTimeToElapsedRealtime(Long.parseLong(endTime));
if (nativeEndTime > nativeSpan.getEndTime$internal()) {
nativeSpan.markEndTime$internal(nativeEndTime);
}
Expand All @@ -245,7 +244,7 @@ private WritableMap nativeSpanToJsSpan(SpanImpl nativeSpan) {
span.putString("traceId", EncodingUtils.toHexString(nativeSpan.getTraceId()));

long unixNanoStartTime = BugsnagClock.INSTANCE.elapsedNanosToUnixTime(nativeSpan.getStartTime$internal());
span.putDouble("startTime", (double)unixNanoStartTime);
span.putString("startTime", Long.toString(unixNanoStartTime));

long parentSpanId = nativeSpan.getParentSpanId();
if (parentSpanId != 0L) {
Expand All @@ -262,8 +261,8 @@ private SpanOptions readableMapToSpanOptions(ReadableMap jsOptions) {
.within(null);

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

Expand Down Expand Up @@ -305,7 +304,7 @@ void exists(String path, Promise promise) {
try {
boolean result = new File(path).exists();
promise.resolve(result);
} catch(Exception e) {
} catch (Exception e) {
promise.reject(e);
}
}
Expand All @@ -314,7 +313,7 @@ void isDir(String path, Promise promise) {
try {
boolean result = new File(path).isDirectory();
promise.resolve(result);
} catch(Exception e) {
} catch (Exception e) {
promise.reject(e);
}
}
Expand All @@ -328,7 +327,7 @@ void ls(String path, Promise promise) {
}

promise.resolve(resultArray);
} catch(Exception e) {
} catch (Exception e) {
promise.reject(e);
}
}
Expand All @@ -347,15 +346,15 @@ void mkdir(String path, Promise promise) {
} else {
promise.reject("EPERM", new Exception("Failed to create directory"));
}
} catch(Exception e) {
} catch (Exception e) {
promise.reject(e);
}
}

void readFile(String path, String encoding, Promise promise) {
File file = new File(path);
StringBuilder fileContent = new StringBuilder((int) file.length());
try(
try (
FileInputStream fin = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fin, encoding);
) {
Expand All @@ -378,13 +377,13 @@ void unlink(String path, Promise promise) {
} else {
promise.reject(new Exception("Failed to delete file/directory"));
}
} catch(Exception e) {
} catch (Exception e) {
promise.reject(e);
}
}

void writeFile(String path, String data, String encoding, Promise promise) {
try(
try (
FileOutputStream fout = new FileOutputStream(path);
Writer w = new OutputStreamWriter(fout, encoding);
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,18 @@ public WritableMap attachToNativeSDK() {
return impl.attachToNativeSDK();
}

@Override
@Override
public WritableMap startNativeSpan(String name, ReadableMap options) {
return impl.startNativeSpan(name, options);
}

@Override
public void endNativeSpan(String spanId, String traceId, double endTime, ReadableMap attributes, Promise promise) {
public void endNativeSpan(String spanId, String traceId, String endTime, ReadableMap attributes, Promise promise) {
impl.endNativeSpan(spanId, traceId, endTime, attributes, promise);
}

@Override
public void markNativeSpanEndTime(String spanId, String traceId, double endTime) {
@Override
public void markNativeSpanEndTime(String spanId, String traceId, String endTime) {
impl.markNativeSpanEndTime(spanId, traceId, endTime);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.Map;

public class BugsnagReactNativePerformance extends ReactContextBaseJavaModule {

private final NativeBugsnagPerformanceImpl impl;

public BugsnagReactNativePerformance(ReactApplicationContext reactContext) {
Expand Down Expand Up @@ -94,12 +94,12 @@ public WritableMap startNativeSpan(String name, ReadableMap options) {
}

@ReactMethod
public void endNativeSpan(String spanId, String traceId, double endTime, ReadableMap attributes, Promise promise) {
impl.endNativeSpan(spanId, traceId, endTime, attributes, promise);
public void endNativeSpan(String spanId, String traceId, String endTime, ReadableMap attributes, Promise promise) {
impl.endNativeSpan(spanId, traceId, endTime, attributes, promise);
}

@ReactMethod(isBlockingSynchronousMethod = true)
public void markNativeSpanEndTime(String spanId, String traceId, double endTime) {
public void markNativeSpanEndTime(String spanId, String traceId, String endTime) {
impl.markNativeSpanEndTime(spanId, traceId, endTime);
}

Expand Down
Loading