Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS 6 - addBreadcrumb - logRNAction #61

Merged
merged 15 commits into from
Aug 14, 2024
49 changes: 34 additions & 15 deletions packages/action-tracker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,32 @@
* @returns an Embrace's middleware instance
*/
export const buildEmbraceMiddleware = () => {
return (store: IMiddleware<IDispatch, any>) =>

Check warning on line 16 in packages/action-tracker/src/index.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'store' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 16 in packages/action-tracker/src/index.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Unexpected any. Specify a different type
(next: IDispatch<IAnyAction>) =>
(action: IAnyAction) => {
async (action: IAnyAction) => {
if (!next || typeof next !== "function") {
console.warn(
"[Embrace] The state managment middleware was not applied succesfully",
);
return 0;
}
const startTime = new Date().getTime();
const attributes = {
name: action.type.toString().toUpperCase(),
payload_size: zip(action.payload || 0).length.toString(),
"emb.type": "sys.rn_action",
outcome: "INCOMPLETE",
};
const spanId = await NativeModules.EmbraceManager.startSpan(
"emb-rn-action",
undefined,
startTime,
);
const attributePromises: Promise<boolean>[] = Object.entries(
TheMutsi marked this conversation as resolved.
Show resolved Hide resolved
attributes,
).map(([key, value]) =>
NativeModules.EmbraceManager.addSpanAttributeToSpan(spanId, key, value),
);

try {
const result = next(action);
Expand All @@ -32,14 +48,15 @@
);
} else {
const endTime = new Date().getTime();
NativeModules.EmbraceManager.logRNAction(
action.type.toString().toUpperCase(),
startTime,
endTime,
{},
zip(action.payload || 0).length,
"SUCCESS",
attributePromises.push(
NativeModules.EmbraceManager.addSpanAttributeToSpan(
spanId,
"outcome",
"SUCCESS",
),
);

NativeModules.EmbraceManager.stopSpan(spanId, "None", endTime);
}
return result;
} catch (e) {
Expand All @@ -49,14 +66,16 @@
);
} else {
const endTime = new Date().getTime();
NativeModules.EmbraceManager.logRNAction(
action.type.toString().toUpperCase(),
startTime,
endTime,
{},
zip(action.payload || 0).length,
"FAIL",

attributePromises.push(
NativeModules.EmbraceManager.addSpanAttributeToSpan(
spanId,
"outcome",
"FAIL",
),
);

NativeModules.EmbraceManager.stopSpan(spanId, "Failure", endTime);
throw e;
}
}
Expand Down
22 changes: 18 additions & 4 deletions packages/core/ios/RNEmbrace/EmbraceManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ @interface RCT_EXTERN_MODULE(EmbraceManager, NSObject)
RCT_EXTERN_METHOD(getDeviceId:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(getLastRunEndState:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(setUserIdentifier:(NSString *)userIdentifier
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
Expand Down Expand Up @@ -54,7 +57,10 @@ @interface RCT_EXTERN_MODULE(EmbraceManager, NSObject)
RCT_EXTERN_METHOD(checkAndSetCodePushBundleURL:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(clearAllUserPersonas:(RCTPromiseResolveBlock)resolve
RCT_EXTERN_METHOD(setUserAsPayer:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(clearUserAsPayer:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(setReactNativeVersion:(NSString *)version
Expand All @@ -75,9 +81,6 @@ @interface RCT_EXTERN_MODULE(EmbraceManager, NSObject)
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(clearUserPersona:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(logMessageWithSeverityAndProperties:(NSString *)message
severity:(NSString *)severity
properties:(NSDictionary *)properties
Expand Down Expand Up @@ -119,6 +122,17 @@ @interface RCT_EXTERN_MODULE(EmbraceManager, NSObject)
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(addUserPersona:(NSString *)persona
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(clearUserPersona:(NSString *)persona
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

RCT_EXTERN_METHOD(clearAllUserPersonas:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)

+ (BOOL)requiresMainQueueSetup
{
return NO;
Expand Down
65 changes: 42 additions & 23 deletions packages/core/ios/RNEmbrace/EmbraceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,12 @@ class EmbraceManager: NSObject {

@objc(addBreadcrumb:resolver:rejecter:)
func addBreadcrumb(_ event: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
//TODO Refactor SPAN
// do {
// try Embrace.client?.add(event: event)
// resolve(true)
// } catch {
// reject(false)
// }
// Add function returns empty if it succeeds, so I specify true as return
if ((Embrace.client?.add(event: .breadcrumb(event))) != nil){
resolve(true)
} else {
reject("ADD_BREADCRUMB", "Error adding breadcrumb", nil)
}
}

@objc
Expand Down Expand Up @@ -210,6 +209,16 @@ class EmbraceManager: NSObject {
reject("CLEAR_ALL_USER_PERSONAS", "Error clearing all User Personas", error)
}
}

@objc(clearUserPersona:resolver:rejecter:)
func clearUserPersona(_ persona:String, resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
do {
try Embrace.client?.metadata.remove(persona: PersonaTag(persona), lifespan: .session)
resolve(true)
}catch let error {
reject("CLEAR_USER_PERSONA", "Error removing User Persona", error)
}
}

@objc(setReactNativeVersion:resolver:rejecter:)
func setReactNativeVersion(_ version: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
Expand Down Expand Up @@ -256,17 +265,7 @@ class EmbraceManager: NSObject {
}
}

@objc(clearUserPersona:resolver:rejecter:)
func clearUserPersona(_ persona:String, resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
do {
try Embrace.client?.metadata.remove(persona: PersonaTag(persona), lifespan: .session)
resolve(true)
}catch let error {
reject("CLEAR_USER_PERSONA", "Error removing User Persona", error)
}
}

@objc(clearUserPersona:severity:properties:resolver:rejecter:)
@objc(logMessageWithSeverityAndProperties:severity:properties:resolver:rejecter:)
func logMessageWithSeverityAndProperties(
_ message: String,
severity: String,
Expand All @@ -288,6 +287,26 @@ class EmbraceManager: NSObject {
resolve(true)

}

@objc
func setUserAsPayer(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
do {
try Embrace.client?.metadata.add(persona: "payer")
resolve(true)
} catch let error {
reject("SET_USER_PAYER", "Error adding User Payer", error)
}
}

@objc
func clearUserAsPayer(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
do {
try Embrace.client?.metadata.remove(persona: "payer", lifespan:.session)
resolve(true)
}catch let error {
reject("CLEAR_USER_PAYER", "Error removing User Payer", error)
}
}

private func severityFromString(from inputString: String) -> LogSeverity {
switch inputString {
Expand Down Expand Up @@ -393,7 +412,7 @@ class EmbraceManager: NSObject {
return events
}

@objc
@objc(startSpan:parentSpanId:startTimeMs:resolver:rejecter:)
func startSpan(
_ name: String,
parentSpanId: String,
Expand Down Expand Up @@ -433,7 +452,7 @@ class EmbraceManager: NSObject {
}
}

@objc
@objc(stopSpan:errorCodeString:endTimeMs:resolver:rejecter:)
func stopSpan(
_ spanId: String,
errorCodeString: String,
Expand Down Expand Up @@ -461,7 +480,7 @@ class EmbraceManager: NSObject {
resolve(true)
}

@objc
@objc(addSpanEventToSpan:name:time:attributes:resolver:rejecter:)
func addSpanEventToSpan(
_ spanId: String,
name: String,
Expand All @@ -486,7 +505,7 @@ class EmbraceManager: NSObject {
resolve(true)
}

@objc
@objc(addSpanAttributeToSpan:key:value:resolver:rejecter:)
func addSpanAttributeToSpan(
_ spanId: String,
key: String,
Expand All @@ -506,7 +525,7 @@ class EmbraceManager: NSObject {
resolve(true)
}

@objc
@objc(recordCompletedSpan:startTimeMs:endTimeMs:errorCodeString:parentSpanId:attributes:events:resolver:rejecter:)
func recordCompletedSpan(
_ name: String,
startTimeMs: Double,
Expand Down
13 changes: 3 additions & 10 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,20 +270,13 @@ export const endSession = () => {
};

export const setUserAsPayer = (): Promise<boolean> => {
// TODO REFACTOR WHEN iOS IMPLEMENT THE METHOD

// return NativeModules.EmbraceManager.setUserAsPayer();

return createFalsePromise();
return NativeModules.EmbraceManager.setUserAsPayer();
};

export const clearUserAsPayer = (): Promise<boolean> => {
// TODO REFACTOR WHEN iOS IMPLEMENT THE METHOD

// return NativeModules.EmbraceManager.clearUserAsPayer();

return createFalsePromise();
return NativeModules.EmbraceManager.clearUserAsPayer();
};

export const recordNetworkRequest = (
url: string,
httpMethod: MethodType,
Expand Down
25 changes: 25 additions & 0 deletions packages/core/test-project/ios/RNEmbraceTests/RNEmbraceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,31 @@ class EmbraceSpansTests: XCTestCase {
XCTAssertEqual(exportedSpans[0].attributes["my-attr2"]!.description, "bar")
}

func testAddSpanAttributeDuplicate() async throws {
module.startSpan("my-span", parentSpanId: "", startTimeMs: 0.0,
resolver: promise.resolve, rejecter: promise.reject)
XCTAssertEqual(promise.resolveCalls.count, 1)
let spanId = (promise.resolveCalls[0] as? String)!

module.addSpanAttributeToSpan(spanId, key: "my-attr1", value: "foo",
resolver: promise.resolve, rejecter: promise.reject)
XCTAssertEqual(promise.resolveCalls.count, 2)
XCTAssertTrue((promise.resolveCalls[1] as? Bool)!)
// Add the same key again, the value should get overridden
module.addSpanAttributeToSpan(spanId, key: "my-attr1", value: "bar",
resolver: promise.resolve, rejecter: promise.reject)
module.stopSpan(spanId, errorCodeString: "", endTimeMs: 0.0,
resolver: promise.resolve, rejecter: promise.reject)

let exportedSpans = try await getExportedSpans()
XCTAssertEqual(exportedSpans.count, 1)
XCTAssertEqual(exportedSpans[0].name, "my-span")
XCTAssertEqual(exportedSpans[0].attributes.count, 3)
XCTAssertEqual(exportedSpans[0].attributes["emb.type"]!.description, "perf")
XCTAssertEqual(exportedSpans[0].attributes["emb.key"]!.description, "true")
XCTAssertEqual(exportedSpans[0].attributes["my-attr1"]!.description, "bar")
}

func testAddSpanAttributeInvalidId() async throws {
module.addSpanAttributeToSpan("invalid", key: "my-attr1", value: "foo",
resolver: promise.resolve, rejecter: promise.reject)
Expand Down
Loading