Skip to content

Commit

Permalink
chore(condo): DOMA-9803 try to monitor memory usage during lifetime (#…
Browse files Browse the repository at this point in the history
…5081)

* chore(condo): DOMA-9803 try to monitor memory usage during lifetime

* chore(condo): DOMA-9803 add some gql data
  • Loading branch information
AleX83Xpert authored Aug 9, 2024
1 parent 7e5211c commit 0841eab
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
5 changes: 5 additions & 0 deletions apps/condo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const {
getPfxCertificateHealthCheck,
} = require('@open-condo/keystone/healthCheck')
const { prepareKeystone } = require('@open-condo/keystone/KSv5v6/v5/prepareKeystone')
const { isMemMonEnabled, catchGC } = require('@open-condo/keystone/memMon/utils')
const { RequestCache } = require('@open-condo/keystone/requestCache')
const { getWebhookModels } = require('@open-condo/webhooks/schema')
const { getWebhookTasks } = require('@open-condo/webhooks/tasks')
Expand Down Expand Up @@ -152,6 +153,10 @@ const extendExpressApp = (app) => {
app.use(Sentry.Handlers.errorHandler())
}

if (isMemMonEnabled()) {
catchGC()
}

module.exports = prepareKeystone({
extendExpressApp,
schemas, tasks, queues: ['low', 'medium', 'high'],
Expand Down
6 changes: 6 additions & 0 deletions packages/keystone/KSv5v6/v5/prepareKeystone.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const { IpBlackListMiddleware } = require('@open-condo/keystone/ipBlackList')
const { registerSchemas } = require('@open-condo/keystone/KSv5v6/v5/registerSchema')
const { getKeystonePinoOptions, GraphQLLoggerPlugin, getLogger } = require('@open-condo/keystone/logging')
const { expressErrorHandler } = require('@open-condo/keystone/logging/expressErrorHandler')
const { ApolloMemMonPlugin } = require('@open-condo/keystone/memMon/plugin')
const { isMemMonEnabled } = require('@open-condo/keystone/memMon/utils')
const metrics = require('@open-condo/keystone/metrics')
const { schemaDocPreprocessor, adminDocPreprocessor, escapeSearchPreprocessor, customAccessPostProcessor } = require('@open-condo/keystone/preprocessors')
const { ApolloRateLimitingPlugin } = require('@open-condo/keystone/rateLimiting')
Expand Down Expand Up @@ -155,6 +157,10 @@ function prepareKeystone ({ onConnect, extendKeystoneConfig, extendExpressApp, s
apolloPlugins.unshift(new ApolloSentryPlugin())
}

if (isMemMonEnabled()) {
apolloPlugins.push(new ApolloMemMonPlugin())
}

return {
keystone,
// NOTE(pahaz): please, check the `executeDefaultServer(..)` to understand how it works.
Expand Down
34 changes: 34 additions & 0 deletions packages/keystone/memMon/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const cuid = require('cuid')
const { get } = require('lodash')

const { logger } = require('./utils')

/** @implements {import('apollo-server-plugin-base').ApolloServerPlugin} */
class ApolloMemMonPlugin {

requestDidStart () {
return {
didResolveOperation: async (requestContext) => {
const operationId = get(requestContext, 'operationId') || cuid()
const mem = process.memoryUsage()
const operationName = get(requestContext, ['request', 'operationName'])
const query = get(requestContext, ['request', 'query'])
const variables = get(requestContext, ['request', 'variables'])

requestContext.operationId = operationId

logger.info({ msg: 'beforeQuery', operationId, operationName, query, variables, data: { mem } })
},
willSendResponse: async (requestContext) => {
const mem = process.memoryUsage()
const operationName = get(requestContext, ['request', 'operationName'])

logger.info({ msg: 'afterQuery', operationId: requestContext.operationId, operationName, data: { mem } })
},
}
}
}

module.exports = {
ApolloMemMonPlugin,
}
23 changes: 23 additions & 0 deletions packages/keystone/memMon/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const process = require('node:process')
const { PerformanceObserver } = require('perf_hooks')

const { getLogger } = require('@open-condo/keystone/logging')

const logger = getLogger('memMon')

function isMemMonEnabled () {
return !process.env['DISABLE_MEM_MON']
}

function catchGC () {
const obs = new PerformanceObserver((list) => {
const entries = list.getEntries()
const mem = process.memoryUsage()

logger.info({ msg: 'afterGC', data: { mem, entriesCount: entries.length, entries } })
})

obs.observe({ entryTypes: ['gc'], buffered: true })
}

module.exports = { isMemMonEnabled, catchGC, logger }

0 comments on commit 0841eab

Please sign in to comment.