From 7757675a5f863944339ddf807a25dd815ecf1b3d Mon Sep 17 00:00:00 2001 From: Vrishab Srivatsa Date: Thu, 21 Mar 2024 20:24:22 +0530 Subject: [PATCH 1/5] =?UTF-8?q?feat(logger):=20calculate=20l=C3=B8ading=20?= =?UTF-8?q?latency=20from=20iframe=20init=20to=20render?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.res | 11 +++++------ src/LoaderController.res | 6 +++--- src/orca-log-catcher/OrcaLogger.res | 15 +++++++++++++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/App.res b/src/App.res index 1019e9a3c..c709b633d 100644 --- a/src/App.res +++ b/src/App.res @@ -1,5 +1,9 @@ @react.component let make = () => { + let (logger, initTimestamp) = React.useMemo0(() => { + let logger = OrcaLogger.make() + (logger, Js.Date.now()) + }) let url = RescriptReactRouter.useUrl() let (integrateError, setIntegrateErrorError) = React.useState(() => false) let setLoggerState = Recoil.useSetRecoilState(RecoilAtoms.loggerAtom) @@ -7,11 +11,6 @@ let make = () => { let paymentMode = CardUtils.getQueryParamsDictforKey(url.search, "componentName") let fullscreenMode = CardUtils.getQueryParamsDictforKey(url.search, "fullscreenType") - let logger = React.useMemo0(() => { - let log = OrcaLogger.make() - log - }) - React.useEffect(() => { setLoggerState(_ => logger) None @@ -39,7 +38,7 @@ let make = () => { | "sepaBankTransfer" => | _ => - + } diff --git a/src/LoaderController.res b/src/LoaderController.res index c9adbab9c..be022b707 100644 --- a/src/LoaderController.res +++ b/src/LoaderController.res @@ -1,6 +1,6 @@ open Utils @react.component -let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => { +let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTimestamp) => { open RecoilAtoms //<...>// let (configAtom, setConfig) = Recoil.useRecoilState(configAtom) @@ -257,8 +257,8 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => { }) } } - - logger.setLogInfo(~value=Window.href, ~eventName=APP_RENDERED, ()) + let latency = Js.Date.now() -. initTimestamp + logger.setLogInfo(~value=Window.href, ~eventName=APP_RENDERED, ~latency, ()) [ ("iframeId", "no-element"->JSON.Encode.string), ("publishableKey", ""->JSON.Encode.string), diff --git a/src/orca-log-catcher/OrcaLogger.res b/src/orca-log-catcher/OrcaLogger.res index 5ce08c4c1..7845c4ba1 100644 --- a/src/orca-log-catcher/OrcaLogger.res +++ b/src/orca-log-catcher/OrcaLogger.res @@ -160,6 +160,7 @@ type setLogInfo = ( ~internalMetadata: string=?, ~eventName: eventName, ~timestamp: string=?, + ~latency: float=?, ~logType: logType=?, ~logCategory: logCategory=?, ~paymentMethod: string=?, @@ -198,6 +199,7 @@ let defaultLoggerConfig = { ~internalMetadata as _=?, ~eventName as _, ~timestamp as _=?, + ~latency as _=?, ~logType as _=?, ~logCategory as _=?, ~paymentMethod as _=?, @@ -219,6 +221,7 @@ let defaultLoggerConfig = { ~internalMetadata as _=?, ~eventName as _, ~timestamp as _=?, + ~latency as _=?, ~logType as _=?, ~logCategory as _=?, ~paymentMethod as _=?, @@ -558,6 +561,7 @@ let make = ( ~internalMetadata="", ~eventName, ~timestamp=?, + ~latency=?, ~logType=INFO, ~logCategory=USER_EVENT, ~paymentMethod="", @@ -565,7 +569,10 @@ let make = ( ) => { let eventNameStr = eventName->eventNameToStrMapper let firstEvent = events.contents->Dict.get(eventNameStr)->Option.isNone - let latency = calculateLatencyHook(~eventName, ()) + let latency = switch latency { + | Some(lat) => lat->Float.toString + | None => calculateLatencyHook(~eventName, ()) + } let localTimestamp = timestamp->Option.getOr(Date.now()->Belt.Float.toString) let localTimestampFloat = localTimestamp->Belt.Float.fromString->Option.getOr(Date.now()) { @@ -657,6 +664,7 @@ let make = ( ~internalMetadata="", ~eventName, ~timestamp=?, + ~latency=?, ~logType=ERROR, ~logCategory=USER_ERROR, ~paymentMethod="", @@ -664,7 +672,10 @@ let make = ( ) => { let eventNameStr = eventName->eventNameToStrMapper let firstEvent = events.contents->Dict.get(eventNameStr)->Option.isNone - let latency = calculateLatencyHook(~eventName, ()) + let latency = switch latency { + | Some(lat) => lat->Float.toString + | None => calculateLatencyHook(~eventName, ()) + } let localTimestamp = timestamp->Option.getOr(Date.now()->Belt.Float.toString) let localTimestampFloat = localTimestamp->Belt.Float.fromString->Option.getOr(Date.now()) { From 31d51fd3b94081b972f555f790675252fdc9b3ff Mon Sep 17 00:00:00 2001 From: Vrishab Srivatsa <136090360+vsrivatsa-juspay@users.noreply.github.com> Date: Fri, 22 Mar 2024 15:06:48 +0530 Subject: [PATCH 2/5] fix: Update src/App.res Co-authored-by: Pritish Budhiraja <1805317@kiit.ac.in> --- src/App.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/App.res b/src/App.res index c709b633d..5b9a43367 100644 --- a/src/App.res +++ b/src/App.res @@ -2,7 +2,7 @@ let make = () => { let (logger, initTimestamp) = React.useMemo0(() => { let logger = OrcaLogger.make() - (logger, Js.Date.now()) +Date.now() }) let url = RescriptReactRouter.useUrl() let (integrateError, setIntegrateErrorError) = React.useState(() => false) From 7afb9ba732bf876f099cde52ea605de3b0fddc39 Mon Sep 17 00:00:00 2001 From: Vrishab Srivatsa Date: Fri, 22 Mar 2024 17:43:51 +0530 Subject: [PATCH 3/5] chore: merged with main --- src/App.res | 3 +-- src/LoaderController.res | 7 ++++--- src/orca-loader/Elements.res | 2 ++ src/orca-loader/Hyper.res | 9 +++++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/App.res b/src/App.res index 5b9a43367..4d49e11d9 100644 --- a/src/App.res +++ b/src/App.res @@ -1,8 +1,7 @@ @react.component let make = () => { let (logger, initTimestamp) = React.useMemo0(() => { - let logger = OrcaLogger.make() -Date.now() + (OrcaLogger.make(), Date.now()) }) let url = RescriptReactRouter.useUrl() let (integrateError, setIntegrateErrorError) = React.useState(() => false) diff --git a/src/LoaderController.res b/src/LoaderController.res index be022b707..01b4b4d10 100644 --- a/src/LoaderController.res +++ b/src/LoaderController.res @@ -257,7 +257,8 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime }) } } - let latency = Js.Date.now() -. initTimestamp + let launchTime = dict->Utils.getFloat("launchTime", 0.0) + let latency = Date.now() -. launchTime logger.setLogInfo(~value=Window.href, ~eventName=APP_RENDERED, ~latency, ()) [ ("iframeId", "no-element"->JSON.Encode.string), @@ -267,8 +268,8 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime ]->Array.forEach(keyPair => { dict->CommonHooks.updateKeys(keyPair, setKeys) }) - - logger.setLogInfo(~eventName=PAYMENT_OPTIONS_PROVIDED, ~value="", ()) + let latency = Date.now() -. initTimestamp + logger.setLogInfo(~eventName=PAYMENT_OPTIONS_PROVIDED, ~latency, ~value="", ()) } } else if dict->getDictIsSome("paymentOptions") { let paymentOptions = dict->Utils.getDictFromObj("paymentOptions") diff --git a/src/orca-loader/Elements.res b/src/orca-loader/Elements.res index 6700963e1..cfe27426e 100644 --- a/src/orca-loader/Elements.res +++ b/src/orca-loader/Elements.res @@ -35,6 +35,7 @@ let make = ( let endpoint = ApiEndpoint.getApiEndPoint(~publishableKey, ()) let appearance = localOptions->Dict.get("appearance")->Option.getOr(Dict.make()->JSON.Encode.object) + let launchTime = localOptions->getFloat("launchTime", 0.0) let fonts = localOptions @@ -247,6 +248,7 @@ let make = ( ("sdkHandleOneClickConfirmPayment", sdkHandleOneClickConfirmPayment->JSON.Encode.bool), ("parentURL", "*"->JSON.Encode.string), ("analyticsMetadata", analyticsMetadata), + ("launchTime", launchTime->JSON.Encode.float), ]->Dict.fromArray let handleApplePayMounted = (event: Types.event) => { diff --git a/src/orca-loader/Hyper.res b/src/orca-loader/Hyper.res index c9756ed76..b584c524a 100644 --- a/src/orca-loader/Hyper.res +++ b/src/orca-loader/Hyper.res @@ -348,12 +348,17 @@ let make = (publishableKey, options: option, analyticsInfo: option { open Promise + let elementsOptionsDict = elementsOptions->JSON.Decode.object + elementsOptionsDict + ->Option.forEach(x => x->Dict.set("launchTime", Date.now()->JSON.Encode.float)) + ->ignore + let clientSecretId = - elementsOptions - ->JSON.Decode.object + elementsOptionsDict ->Option.flatMap(x => x->Dict.get("clientSecret")) ->Option.flatMap(JSON.Decode.string) ->Option.getOr("") + let elementsOptions = elementsOptionsDict->Option.mapOr(elementsOptions, JSON.Encode.object) clientSecret := clientSecretId Js.Promise.make((~resolve, ~reject as _) => { logger.setClientSecret(clientSecretId) From dd0ad73b71766d019f149634bb7f4e302c56ae44 Mon Sep 17 00:00:00 2001 From: Vrishab Srivatsa Date: Fri, 22 Mar 2024 17:53:28 +0530 Subject: [PATCH 4/5] feat(logger): added latency for LOADER_CHANGED event --- src/LoaderController.res | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/LoaderController.res b/src/LoaderController.res index 01b4b4d10..ac6319080 100644 --- a/src/LoaderController.res +++ b/src/LoaderController.res @@ -15,6 +15,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime let setIsGooglePayReady = Recoil.useSetRecoilState(isGooglePayReady) let setIsApplePayReady = Recoil.useSetRecoilState(isApplePayReady) let (divH, setDivH) = React.useState(_ => 0.0) + let (launchTime, setLaunchTime) = React.useState(_ => 0.0) let {showCardFormByDefault, paymentMethodOrder} = optionsPayment let divRef = React.useRef(Nullable.null) @@ -130,15 +131,21 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime showCardFormByDefault && Utils.checkPriorityList(paymentMethodOrder) ? SemiLoaded : Loading | x => x } + let latency = Js.Date.now() -. launchTime switch updatedState { - | Loaded(_) => logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ()) - | Loading => logger.setLogInfo(~value="Loading", ~eventName=LOADER_CHANGED, ()) + | Loaded(_) => logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ~latency, ()) + | Loading => logger.setLogInfo(~value="Loading", ~eventName=LOADER_CHANGED, ~latency, ()) | SemiLoaded => { setList(_ => updatedState) - logger.setLogInfo(~value="SemiLoaded", ~eventName=LOADER_CHANGED, ()) + logger.setLogInfo(~value="SemiLoaded", ~eventName=LOADER_CHANGED, ~latency, ()) } | LoadError(x) => - logger.setLogError(~value="LoadError: " ++ x->JSON.stringify, ~eventName=LOADER_CHANGED, ()) + logger.setLogError( + ~value="LoadError: " ++ x->JSON.stringify, + ~eventName=LOADER_CHANGED, + ~latency, + (), + ) } Window.addEventListener("click", ev => handleOnClickPostMessage(~targetOrigin=keys.parentURL, ev) @@ -257,7 +264,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime }) } } - let launchTime = dict->Utils.getFloat("launchTime", 0.0) + setLaunchTime(_ => dict->Utils.getFloat("launchTime", 0.0)) let latency = Date.now() -. launchTime logger.setLogInfo(~value=Window.href, ~eventName=APP_RENDERED, ~latency, ()) [ @@ -341,6 +348,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime } if dict->getDictIsSome("paymentMethodList") { let list = dict->getJsonObjectFromDict("paymentMethodList") + let latency = Js.Date.now() -. launchTime let updatedState: PaymentType.loadType = list == Dict.make()->JSON.Encode.object ? LoadError(list) @@ -352,11 +360,12 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime isNonEmptyPaymentMethodList ? Loaded(list) : LoadError(list) } switch updatedState { - | Loaded(_) => logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ()) + | Loaded(_) => logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ~latency, ()) | LoadError(x) => logger.setLogError( ~value="LoadError: " ++ x->JSON.stringify, ~eventName=LOADER_CHANGED, + ~latency, (), ) | _ => () From 23e263784b98142209fb83455829acfd41d9d70b Mon Sep 17 00:00:00 2001 From: Vrishab Srivatsa Date: Tue, 26 Mar 2024 17:48:14 +0530 Subject: [PATCH 5/5] refactor(logger): renamed latency vars --- src/LoaderController.res | 47 ++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/src/LoaderController.res b/src/LoaderController.res index ac6319080..1d354db58 100644 --- a/src/LoaderController.res +++ b/src/LoaderController.res @@ -131,19 +131,26 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime showCardFormByDefault && Utils.checkPriorityList(paymentMethodOrder) ? SemiLoaded : Loading | x => x } - let latency = Js.Date.now() -. launchTime + let finalLoadLatency = Js.Date.now() -. launchTime switch updatedState { - | Loaded(_) => logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ~latency, ()) - | Loading => logger.setLogInfo(~value="Loading", ~eventName=LOADER_CHANGED, ~latency, ()) + | Loaded(_) => + logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ~latency=finalLoadLatency, ()) + | Loading => + logger.setLogInfo(~value="Loading", ~eventName=LOADER_CHANGED, ~latency=finalLoadLatency, ()) | SemiLoaded => { setList(_ => updatedState) - logger.setLogInfo(~value="SemiLoaded", ~eventName=LOADER_CHANGED, ~latency, ()) + logger.setLogInfo( + ~value="SemiLoaded", + ~eventName=LOADER_CHANGED, + ~latency=finalLoadLatency, + (), + ) } | LoadError(x) => logger.setLogError( ~value="LoadError: " ++ x->JSON.stringify, ~eventName=LOADER_CHANGED, - ~latency, + ~latency=finalLoadLatency, (), ) } @@ -265,8 +272,13 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime } } setLaunchTime(_ => dict->Utils.getFloat("launchTime", 0.0)) - let latency = Date.now() -. launchTime - logger.setLogInfo(~value=Window.href, ~eventName=APP_RENDERED, ~latency, ()) + let initLoadlatency = Date.now() -. launchTime + logger.setLogInfo( + ~value=Window.href, + ~eventName=APP_RENDERED, + ~latency=initLoadlatency, + (), + ) [ ("iframeId", "no-element"->JSON.Encode.string), ("publishableKey", ""->JSON.Encode.string), @@ -275,8 +287,13 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime ]->Array.forEach(keyPair => { dict->CommonHooks.updateKeys(keyPair, setKeys) }) - let latency = Date.now() -. initTimestamp - logger.setLogInfo(~eventName=PAYMENT_OPTIONS_PROVIDED, ~latency, ~value="", ()) + let renderLatency = Date.now() -. initTimestamp + logger.setLogInfo( + ~eventName=PAYMENT_OPTIONS_PROVIDED, + ~latency=renderLatency, + ~value="", + (), + ) } } else if dict->getDictIsSome("paymentOptions") { let paymentOptions = dict->Utils.getDictFromObj("paymentOptions") @@ -348,7 +365,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime } if dict->getDictIsSome("paymentMethodList") { let list = dict->getJsonObjectFromDict("paymentMethodList") - let latency = Js.Date.now() -. launchTime + let finalLoadlatency = Js.Date.now() -. launchTime let updatedState: PaymentType.loadType = list == Dict.make()->JSON.Encode.object ? LoadError(list) @@ -360,12 +377,18 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime isNonEmptyPaymentMethodList ? Loaded(list) : LoadError(list) } switch updatedState { - | Loaded(_) => logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ~latency, ()) + | Loaded(_) => + logger.setLogInfo( + ~value="Loaded", + ~eventName=LOADER_CHANGED, + ~latency=finalLoadlatency, + (), + ) | LoadError(x) => logger.setLogError( ~value="LoadError: " ++ x->JSON.stringify, ~eventName=LOADER_CHANGED, - ~latency, + ~latency=finalLoadlatency, (), ) | _ => ()