Skip to content

Commit

Permalink
📈 Graphql response time logs (#5730)
Browse files Browse the repository at this point in the history
* POC version

* Few fixes and debug log for vercel

* Make sure to set query name even if geolocation is missing

* Replace console log with a call to logs service
  • Loading branch information
WRadoslaw committed Feb 9, 2024
1 parent 593008c commit 2f42279
Showing 1 changed file with 55 additions and 1 deletion.
56 changes: 55 additions & 1 deletion packages/atlas/src/api/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,34 @@ import { createClient } from 'graphql-ws'

import { ORION_GRAPHQL_URL, QUERY_NODE_GRAPHQL_SUBSCRIPTION_URL } from '@/config/env'
import { useUserLocationStore } from '@/providers/userLocation'
import { UserEventsLogger } from '@/utils/logs'

import { cache } from './cache'

const initializePerformanceObserver = () => {
try {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (['fetch', 'xmlhttprequest'].includes((entry as PerformanceResourceTiming).initiatorType)) {
const queryString = entry.name.split('?')?.[1]
const params = new URLSearchParams(queryString)
const queryType = params.get('queryName')
UserEventsLogger.logUserEvent('request-response-time', {
requestName: queryType ?? entry.name,
timeToComplete: entry.duration,
})
}
}
})
// Start listening for `resource` entries to be dispatched.
observer.observe({ type: 'resource', buffered: true })
} catch (e) {
// Do nothing if the browser doesn't support this API.
}
}

initializePerformanceObserver()

const delayLink = new ApolloLink((operation, forward) => {
const ctx = operation.getContext()
if (!ctx.delay) {
Expand All @@ -31,11 +56,40 @@ export const createApolloClient = () => {
})
)

const orionLink = ApolloLink.from([delayLink, new HttpLink({ uri: ORION_GRAPHQL_URL, credentials: 'include' })])
const orionLink = ApolloLink.from([
delayLink,
new HttpLink({
uri: ORION_GRAPHQL_URL,
credentials: 'include',
fetch: async (uri, options) => {
const queryName = options?.headers
? (options.headers?.['queryname' as keyof typeof options.headers] as string)
: null
const queryString = queryName ? `?queryName=${queryName}` : ''
return fetch(`${uri}${queryString}`, options)
},
}),
])

const operationSplitLink = split(
({ query, setContext }) => {
const locationStore = useUserLocationStore.getState()
const firstDefinition = query.definitions[0]
let queryName: string | null | undefined = null
if (firstDefinition.kind === 'OperationDefinition' && firstDefinition.operation === 'query') {
queryName = firstDefinition.name?.value
}

if (queryName) {
setContext(({ headers }: Record<string, object>) => {
return {
headers: {
...headers,
...(queryName ? { queryName } : {}),
},
}
})
}

if (
!locationStore.disableUserLocation &&
Expand Down

0 comments on commit 2f42279

Please sign in to comment.