Skip to content

Commit

Permalink
feat(logger): calculate loading latency from iframe init to render (#248
Browse files Browse the repository at this point in the history
)

Co-authored-by: Pritish Budhiraja <[email protected]>
  • Loading branch information
vsrivatsa-edinburgh and Pritish Budhiraja authored Mar 27, 2024
1 parent b3097f4 commit 38387ed
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 20 deletions.
10 changes: 4 additions & 6 deletions src/App.res
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
@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)

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
Expand Down Expand Up @@ -41,7 +39,7 @@ let make = () => {
| "sepaBankTransfer" =>
<BankTransfersPopup transferType=fullscreenMode />
| _ =>
<LoaderController paymentMode setIntegrateErrorError logger>
<LoaderController paymentMode setIntegrateErrorError logger initTimestamp>
<Payment paymentMode integrateError logger />
</LoaderController>
}
Expand Down
53 changes: 43 additions & 10 deletions src/LoaderController.res
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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),
Expand All @@ -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")
Expand Down Expand Up @@ -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)
Expand All @@ -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,
(),
)
| _ => ()
Expand Down
2 changes: 2 additions & 0 deletions src/orca-loader/Elements.res
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) => {
Expand Down
9 changes: 7 additions & 2 deletions src/orca-loader/Hyper.res
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,17 @@ let make = (publishableKey, options: option<JSON.t>, analyticsInfo: option<JSON.

let elements = elementsOptions => {
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)
Expand Down
15 changes: 13 additions & 2 deletions src/orca-log-catcher/OrcaLogger.res
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type setLogInfo = (
~internalMetadata: string=?,
~eventName: eventName,
~timestamp: string=?,
~latency: float=?,
~logType: logType=?,
~logCategory: logCategory=?,
~paymentMethod: string=?,
Expand Down Expand Up @@ -198,6 +199,7 @@ let defaultLoggerConfig = {
~internalMetadata as _=?,
~eventName as _,
~timestamp as _=?,
~latency as _=?,
~logType as _=?,
~logCategory as _=?,
~paymentMethod as _=?,
Expand All @@ -219,6 +221,7 @@ let defaultLoggerConfig = {
~internalMetadata as _=?,
~eventName as _,
~timestamp as _=?,
~latency as _=?,
~logType as _=?,
~logCategory as _=?,
~paymentMethod as _=?,
Expand Down Expand Up @@ -558,14 +561,18 @@ let make = (
~internalMetadata="",
~eventName,
~timestamp=?,
~latency=?,
~logType=INFO,
~logCategory=USER_EVENT,
~paymentMethod="",
(),
) => {
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())
{
Expand Down Expand Up @@ -657,14 +664,18 @@ let make = (
~internalMetadata="",
~eventName,
~timestamp=?,
~latency=?,
~logType=ERROR,
~logCategory=USER_ERROR,
~paymentMethod="",
(),
) => {
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())
{
Expand Down

0 comments on commit 38387ed

Please sign in to comment.