Skip to content

Commit

Permalink
chore: Add datadog integration (#8254)
Browse files Browse the repository at this point in the history
<!--
Before opening a pull request, please read the [contributing
guidelines](https://github.com/pancakeswap/pancake-frontend/blob/develop/CONTRIBUTING.md)
first
-->

<!--
copilot:all
-->
### <samp>🤖 Generated by Copilot at eddc0ff</samp>

### Summary
🐶📝🕵️‍♂️

<!--
1. 🐶 - This emoji represents Datadog, the logging and monitoring service
that is integrated with the web app. It also conveys the idea of
tracking and observing the web app's behavior and performance.
2. 📝 - This emoji represents logging, the process of recording and
storing information about the web app's events and activities. It also
conveys the idea of documenting and reporting the web app's status and
issues.
3. 🕵️‍♂️ - This emoji represents monitoring, the process of measuring
and analyzing the web app's performance and quality. It also conveys the
idea of inspecting and detecting the web app's problems and
opportunities.
-->
This pull request adds logging and monitoring of the web app and the web
worker using Datadog browser logs. It adds a new dependency for
`@datadog/browser-logs`, a new environment variable for
`NEXT_PUBLIC_DATADOG_CLIENT_TOKEN`, and some utility files for
configuring and polyfilling the logger. It also removes an unused
dependency for `react-fast-marquee`.

> _Sing, O Muse, of the glorious deeds of the web app makers,_
> _Who, with skill and cunning, added the logs of Datadog,_
> _The swift and faithful messenger of the cloud-born Zeus,_
> _To monitor and trace their code, both in browser and in worker._

### Walkthrough
* Add and configure Datadog browser logs library for logging and
monitoring web app and web worker
([link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-c8e463bbf676c362fbc68386873a43c51bfb1a1bb136822808f18c7f2c9fb591R9),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-14b60f636e1a2b0061da57aaf231cb1ed15a5dc0c592425ed82e58fec95d42d8R35),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-cb95365019f7ba2030863c54e03dafdfde7363d4004781eab13cf7e887fa31deL1-R6),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-cb95365019f7ba2030863c54e03dafdfde7363d4004781eab13cf7e887fa31deR19),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-cb95365019f7ba2030863c54e03dafdfde7363d4004781eab13cf7e887fa31deL31-R35),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-cb95365019f7ba2030863c54e03dafdfde7363d4004781eab13cf7e887fa31deR41-R42),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-a6e33c8aa8509a097c0e5157cbd63aa8e3f373104ea573615f15d7c6804582fbR1-R32),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-96b658c988c8717a5c20e2588b1d8c183008f94ee7a20c4d7acd8cdf1beb8515R1-R103),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbR562-R564),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbR4984-R4998))
* Remove `react-fast-marquee` dependency and replace it with custom
component for scrolling text effect
([link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-14b60f636e1a2b0061da57aaf231cb1ed15a5dc0c592425ed82e58fec95d42d8L92-R94))
* Update `entities` dependency from version 4.4.0 to 4.5.0 for encoding
and decoding HTML entities
([link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbL9452-R9470),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbL15228-R15246),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbL15422-R15441),
[link](https://github.com/pancakeswap/pancake-frontend/pull/8254/files?diff=unified&w=0#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfdd7f53ee026bbL21486-R21504))
  • Loading branch information
chefjackson authored Oct 31, 2023
1 parent cde87fc commit 189b362
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 16 deletions.
1 change: 1 addition & 0 deletions apps/web/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ SERVER_NODE_REAL_API_ETH=
SERVER_NODE_REAL_API_GOERLI=
NEXT_PUBLIC_MERCURYO_WIDGET_ID=
NEXT_PUBLIC_WALLCHAIN_BSC_KEY=
NEXT_PUBLIC_DATADOG_CLIENT_TOKEN=
3 changes: 2 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"node": ">=16.0.0"
},
"dependencies": {
"@datadog/browser-logs": "^5.1.0",
"@gelatonetwork/limit-orders-lib": "^4.1.0",
"@gnosis.pm/safe-apps-wagmi": "^1.2.0",
"@next/bundle-analyzer": "13.0.7",
Expand Down Expand Up @@ -90,8 +91,8 @@
"react-datepicker": "^4.8.0",
"react-device-detect": "^2.1.2",
"react-dom": "^18.2.0",
"react-redux": "^8.0.5",
"react-fast-marquee": "^1.6.0",
"react-redux": "^8.0.5",
"react-transition-group": "^4.4.5",
"react-window": "^1.8.7",
"recharts": "2.1.15",
Expand Down
22 changes: 14 additions & 8 deletions apps/web/src/quote-worker.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'utils/workerPolyfill'
import { SmartRouter } from '@pancakeswap/smart-router/evm'
import { Call } from 'state/multicall/actions'
import { fetchChunk } from 'state/multicall/fetchChunk'
import { getViemClients } from 'utils/viem'
import { getLogger } from 'utils/datadog'

const { parseCurrency, parseCurrencyAmount, parsePool, serializeTrade } = SmartRouter.Transformer

Expand All @@ -14,6 +16,7 @@ export type WorkerGetBestTradeEvent = [
]

const fetch_ = fetch
const logger = getLogger('quote-rpc', { forwardErrorsToLogs: false })

const fetchWithLogging = async (url: RequestInfo | URL, init?: RequestInit) => {
const start = Date.now()
Expand All @@ -27,15 +30,18 @@ const fetchWithLogging = async (url: RequestInfo | URL, init?: RequestInit) => {
const response = await fetch_(url, init)
const end = Date.now()
if (urlString && size) {
if (!urlString.includes('vercel-vitals.axiom.co')) {
if (process.env.NEXT_PUBLIC_VERCEL_ENV !== 'production') {
// eslint-disable-next-line no-console
console.log('QuoteRPC', {
url: urlString,
size,
time: end - start,
status: response.status,
if (!urlString.includes('datadoghq.com')) {
try {
logger.info('Quote RPC', {
rpc: {
duration: end - start,
url: urlString,
size,
status: response.status,
},
})
} catch (e) {
console.error(e)
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions apps/web/src/utils/datadog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { datadogLogs, LogsInitConfiguration } from '@datadog/browser-logs'

// TODO: move to env if needed
const DATA_DOG_SITE = 'us3.datadoghq.com'

try {
datadogLogs.init({
clientToken: process.env.NEXT_PUBLIC_DATADOG_CLIENT_TOKEN || '',
env: process.env.NEXT_PUBLIC_VERCEL_ENV,
version: process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA,
site: DATA_DOG_SITE,
forwardErrorsToLogs: true,
sessionSampleRate: 100,
service: 'pancakeswap-web',
})
} catch (e) {
console.error(e)
}

export function getLogger(name: string, config?: Partial<LogsInitConfiguration>) {
const logger = datadogLogs.getLogger(name)
if (logger) {
return logger
}
return datadogLogs.createLogger(name, {
handler: process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' ? 'http' : ['console', 'http'],
context: {
service: `pancakeswap-web-${name}`,
...config,
},
})
}

export const logger = getLogger('main')
5 changes: 3 additions & 2 deletions apps/web/src/utils/log.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Currency } from '@pancakeswap/swap-sdk-core'
import { log } from 'next-axiom'

import { logger } from './datadog'

export const logTx = ({ account, hash, chainId }: { account: string; hash: string; chainId: number }) => {
fetch(`/api/_log/${account}/${chainId}/${hash}`)
Expand All @@ -25,7 +26,7 @@ export const logSwap = ({
type: 'V2Swap' | 'SmartSwap' | 'StableSwap' | 'MarketMakerSwap' | 'V3SmartSwap'
}) => {
try {
log.info(type, {
logger.info(type, {
inputAddress: input.isToken ? input.address.toLowerCase() : input.symbol,
outputAddress: output.isToken ? output.address.toLowerCase() : output.symbol,
inputAmount,
Expand Down
103 changes: 103 additions & 0 deletions apps/web/src/utils/workerPolyfill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
globalThis.document = {
readyState: 'complete',
getElementsByTagName: () => [] as any,
// @ts-expect-error partial polyfill for @datadog/browser-logs
location: {
hostname: 'hostname.com',
href: '',
},
get cookie() {
return ''
},
set cookie(cookie: any) {},
addEventListener: () => {},
removeEventListener: () => {},
}

globalThis.window = {
TextEncoder: globalThis.TextEncoder,
fetch: globalThis.fetch,
// @ts-expect-error partial polyfill for @datadog/browser-logs
location: {
hostname: '',
href: '',
},
addEventListener: () => {},
removeEventListener: () => {},
}

globalThis.performance = {
// @ts-expect-error partial polyfill for @datadog/browser-logs
timing: {
navigationStart: 0,
},
now: () => 0,
}

class XMLHttpRequestWithFetch {
private method: string | null

private url: string | null

private status: number

private listeners: any

constructor() {
this.method = null
this.url = null
this.status = 500
this.listeners = {}
}

open(method: string, url: string) {
this.method = method
this.url = url
}

addEventListener(eventName: string, cb: any) {
if (!this.listeners[eventName]) {
this.listeners[eventName] = []
}
this.listeners[eventName].push(cb)
}

removeEventListener(eventName: string, cb: any) {
const handlers = this.listeners[eventName]
if (handlers) {
const restOfHandlers = handlers.filter((callback: any) => callback !== cb)
if (restOfHandlers && restOfHandlers.length) {
this.listeners[eventName] = restOfHandlers
} else {
delete this.listeners[eventName]
}
}
}

send(data: any) {
let _body = data
if (typeof data === 'object') {
_body = JSON.stringify(data)
}
if (!this.url) {
return
}
fetch(this.url, {
method: this.method || 'GET',
body: _body,
})
.then((response) => {
this.status = response.status
// notify all listeners that we're done
Object.keys(this.listeners).forEach((event) => {
this.listeners[event].forEach((handler: any) => handler(response))
})
})
.catch(() => {
// @TODO: probably we should handle the failing case.
})
}
}

// @ts-expect-error partial polyfill for @datadog/browser-logs
globalThis.XMLHttpRequest = XMLHttpRequestWithFetch
28 changes: 23 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 comments on commit 189b362

@vercel
Copy link

@vercel vercel bot commented on 189b362 Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

uikit – ./packages/uikit

uikit.pancake.run
uikit-git-develop.pancake.run

@vercel
Copy link

@vercel vercel bot commented on 189b362 Oct 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.