diff --git a/src/App.res b/src/App.res
index 5a24a650a..b65ae89ef 100644
--- a/src/App.res
+++ b/src/App.res
@@ -1,5 +1,8 @@
@react.component
let make = () => {
+ let (logger, initTimestamp) = React.useMemo0(() => {
+ (OrcaLogger.make(), Date.now())
+ })
let url = RescriptReactRouter.useUrl()
let (integrateError, setIntegrateErrorError) = React.useState(() => false)
let setLoggerState = Recoil.useSetRecoilState(RecoilAtoms.loggerAtom)
@@ -7,11 +10,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
@@ -41,7 +39,7 @@ let make = () => {
| "sepaBankTransfer" =>
| _ =>
-
+
}
diff --git a/src/LoaderController.res b/src/LoaderController.res
index c9adbab9c..1d354db58 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)
@@ -15,6 +15,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
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,28 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
showCardFormByDefault && Utils.checkPriorityList(paymentMethodOrder) ? SemiLoaded : Loading
| x => x
}
+ let finalLoadLatency = 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=finalLoadLatency, ())
+ | Loading =>
+ logger.setLogInfo(~value="Loading", ~eventName=LOADER_CHANGED, ~latency=finalLoadLatency, ())
| SemiLoaded => {
setList(_ => updatedState)
- logger.setLogInfo(~value="SemiLoaded", ~eventName=LOADER_CHANGED, ())
+ logger.setLogInfo(
+ ~value="SemiLoaded",
+ ~eventName=LOADER_CHANGED,
+ ~latency=finalLoadLatency,
+ (),
+ )
}
| LoadError(x) =>
- logger.setLogError(~value="LoadError: " ++ x->JSON.stringify, ~eventName=LOADER_CHANGED, ())
+ logger.setLogError(
+ ~value="LoadError: " ++ x->JSON.stringify,
+ ~eventName=LOADER_CHANGED,
+ ~latency=finalLoadLatency,
+ (),
+ )
}
Window.addEventListener("click", ev =>
handleOnClickPostMessage(~targetOrigin=keys.parentURL, ev)
@@ -257,8 +271,14 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
})
}
}
-
- logger.setLogInfo(~value=Window.href, ~eventName=APP_RENDERED, ())
+ setLaunchTime(_ => dict->Utils.getFloat("launchTime", 0.0))
+ 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),
@@ -267,8 +287,13 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
]->Array.forEach(keyPair => {
dict->CommonHooks.updateKeys(keyPair, setKeys)
})
-
- logger.setLogInfo(~eventName=PAYMENT_OPTIONS_PROVIDED, ~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")
@@ -340,6 +365,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
}
if dict->getDictIsSome("paymentMethodList") {
let list = dict->getJsonObjectFromDict("paymentMethodList")
+ let finalLoadlatency = Js.Date.now() -. launchTime
let updatedState: PaymentType.loadType =
list == Dict.make()->JSON.Encode.object
? LoadError(list)
@@ -351,11 +377,18 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger) => {
isNonEmptyPaymentMethodList ? Loaded(list) : LoadError(list)
}
switch updatedState {
- | Loaded(_) => logger.setLogInfo(~value="Loaded", ~eventName=LOADER_CHANGED, ())
+ | Loaded(_) =>
+ logger.setLogInfo(
+ ~value="Loaded",
+ ~eventName=LOADER_CHANGED,
+ ~latency=finalLoadlatency,
+ (),
+ )
| LoadError(x) =>
logger.setLogError(
~value="LoadError: " ++ x->JSON.stringify,
~eventName=LOADER_CHANGED,
+ ~latency=finalLoadlatency,
(),
)
| _ => ()
diff --git a/src/orca-loader/Elements.res b/src/orca-loader/Elements.res
index ea15add96..65c015c37 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)
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())
{