Last active
October 20, 2021 20:26
-
-
Save mape/56a689fcff9e73c50d377a89241cb623 to your computer and use it in GitHub Desktop.
Elastic APM node client instrumenting Prisma 2 queries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { condensePrismaQuery } from './utils'; | |
// Screenshot of a trace sample: https://i.imgur.com/XuhuQFq.png | |
// Service: https://www.elastic.co/apm | |
// Node module: https://github.com/elastic/apm-agent-nodejs | |
// Prisma: https://www.prisma.io/ | |
// Using "@prisma/client": "dev" | |
// Thanks to https://github.com/prisma/prisma/pull/2902 | |
const apmPatchPrisma = ( | |
prisma: PrismaClient<{}, never>, | |
apm: any /*Agent*/ | |
) => { | |
// "as any" because these hooks are not available in the TypeScript types yet | |
(prisma as any).use('all', async (request: any) => { | |
const name = condensePrismaQuery(request.params.args); | |
const type = 'db'; | |
const subType = 'prisma'; | |
const action = 'query'; | |
const apmSpan = apm.startSpan(name, type, subType, action); | |
const result = await request.fetch(request.params); | |
apmSpan && apmSpan.end(); | |
return result; | |
}); | |
}; | |
export default apmPatchPrisma; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const apm = require('elastic-apm-node').start({ | |
serviceName: 'app', | |
secretToken: process.env.AP_TOKEN, | |
serverUrl: process.env.APM_URL | |
}); | |
import { PrismaClient } from '@prisma/client'; | |
import apmPatchPrisma from './lib/apmPatchPrisma'; | |
const prisma = new PrismaClient(); | |
apmPatchPrisma(prisma, apm); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const condensePrismaQuery = (prismaQuery: Object, delimiter = '.') => { | |
const result = {}; | |
const flatten = (obj: any, stack: any) => { | |
Object.keys(obj).forEach((key) => { | |
const s = stack | |
.concat([key === 'select' ? undefined : key.trim()]) | |
.filter(Boolean); | |
const child = obj[key]; | |
if (typeof child === 'object') { | |
flatten(child, s); | |
} else { | |
const twoLastInChain = s | |
.slice(s.length - 2, s.length) | |
.join(delimiter); | |
result[twoLastInChain] = true; | |
} | |
}); | |
}; | |
flatten(prismaQuery, []); | |
const output = Object.keys(result).join(', '); | |
return `Prisma: ${output}`; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment