Skip to content

Instantly share code, notes, and snippets.

@Jackman3005
Created May 20, 2024 04:45
Show Gist options
  • Save Jackman3005/c11c751c6d5fac4f002d4d369f20932b to your computer and use it in GitHub Desktop.
Save Jackman3005/c11c751c6d5fac4f002d4d369f20932b to your computer and use it in GitHub Desktop.
Prisma Query Debugging code
function buildPrismaWithQueryDebugging(
sqlQueryReportingThresholdMs: number,
prismaActionReportingThresholdMs: number
) {
const prisma = new PrismaClient({
log: [
{
emit: "event",
level: "query",
},
],
});
prisma.$on("query", (e) => {
try {
if (!/^(UPDATE|SELECT|INSERT|DELETE).*/g.test(e.query)) {
// skip BEGIN/COMMIT/etc queries
return;
}
if (e.duration < sqlQueryReportingThresholdMs) {
// threshold for what to record, increase if too many queries printed, decrease if not enough
return;
}
// replace raw date characters with the postgres timestamp syntax wrapped in a string
const queryParamsArray = e.params.replaceAll(
/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{0,3} UTC)/g,
(match) => {
return `TIMESTAMP WITH TIME ZONE '${match}'`;
}
);
const paramObjs = JSON.parse(queryParamsArray);
const rebuiltQuery = (e.query || "").replaceAll(
/\$(\d+)/g,
(_matchedString, paramIndex) => {
let param = paramObjs[parseInt(paramIndex) - 1];
if (typeof param === "string") {
if (!param.startsWith("TIMESTAMP")) {
param = `'${param.replace("'", "\\'")}'`;
}
}
return param;
}
);
LOG.debug(
`\n\nLONG QUERY DETECTED - ${e.duration}ms - Query below:\n${rebuiltQuery}\n`,
{ durationMs: e.duration }
);
} catch (err) {
LOG.error("Unknown error in long query reporter: ", err);
}
});
return prisma.$extends({
query: {
async $allOperations({ operation, model, args, query }) {
const timeStart = Date.now();
const result = await query(args);
const timeEnd = Date.now();
try {
const duration = timeEnd - timeStart;
if (duration > prismaActionReportingThresholdMs) {
let resultStats;
if (Array.isArray(result)) {
resultStats = `NumItems: ${result.length}, RawCharacterSize: ${
JSON.stringify(result).length
}`;
} else {
resultStats = `RawCharacterSize: ${
JSON.stringify(result).length
}`;
}
LOG.warn(
`LONG PRISMA ACTION DETECTED - ${duration}ms - ${model}.${operation} - Result Stats -> ${resultStats}`,
{
error: new Error("LONG PRISMA ACTION DETECTED"),
durationMs: duration,
model,
operation,
args,
}
);
}
} catch (error) {
LOG.error("Unknown error in long action reporter: ", { error });
}
return result;
},
},
});
}
const _prisma = ENV.DEBUG_PRISMA_QUERIES
? buildPrismaWithQueryDebugging(10, 30)
: new PrismaClient();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment