In prisma's $on event, nest-cls did not get normal context data
Closed this issue · 1 comments
ahuijiLearning commented
app.service.ts
import { Injectable } from '@nestjs/common';
import { logger } from './logger/myLogger.service';
import { PrismaService } from './prisma/prisma.service';
@Injectable()
export class AppService {
constructor(private prisma: PrismaService) {}
async getHello(): Promise<string> {
logger.log('test');
const row = await this.prisma.user.findFirst({ where: { id: 1 } });
console.log('row', row);
logger.log('test-end');
return 'Hello World!22';
}
}
prisma.service.ts
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { Prisma, PrismaClient } from '@prisma/client';
import { logger } from 'src/logger/myLogger.service';
@Injectable()
export class PrismaService
extends PrismaClient<Prisma.PrismaClientOptions, 'query'>
implements OnModuleInit, OnModuleDestroy
{
constructor() {
super({ log: [{ emit: 'event', level: 'query' }] });
}
async onModuleInit() {
await this.$connect();
this.$on('query', (event: Prisma.QueryEvent) => {
let queryMsg = event.query;
try {
const params = JSON.parse(event.params) as any[];
for (const k of params) {
queryMsg = queryMsg.replace('?', ` ${k} `);
}
queryMsg += ';';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (e) {
queryMsg += `; params ${event.params}`;
}
logger.log(`======sql_log=====\n${queryMsg} ${event.duration}ms`);
});
this.$use(async (params, next) => {
console.log(params);
const before = Date.now();
const result = await next(params);
const after = Date.now();
logger.log(
`Query ${params.model}.${params.action} took ${after - before}ms`,
);
return result;
});
}
async onModuleDestroy() {
await this.$disconnect();
}
}
myLogger.service.ts
import {
ConsoleLogger,
Global,
Injectable,
LoggerService,
LogLevel,
Scope,
} from '@nestjs/common';
import { ClsServiceManager } from 'nestjs-cls';
type formatType = {
level: LogLevel;
};
export class TraceStore {
traceId: string;
ua: string;
reqUrl: string;
reqMethod: string;
time: number;
}
@Global()
@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends ConsoleLogger implements LoggerService {
log(...params: unknown[]): void {
super.log(this.formatParamStyle(params, { level: 'log' }));
}
formatParamStyle(messages: unknown[], options: formatType): string {
const { level } = options;
const rows: string[] = [];
const cls = ClsServiceManager.getClsService();
const trace = cls.get('trace') as TraceStore;
const time = trace
? super.colorize(`+${+new Date() - trace.time}ms`, 'warn')
: '';
if (trace) {
rows.push(trace.traceId, trace.reqUrl, trace.reqMethod);
}
for (const message of messages) {
if (typeof message === 'object') {
rows.push(JSON.stringify(message));
} else {
rows.push(String(message));
}
}
return `${time} ${super.colorize(rows.join(' '), level)}`;
}
}
export const logger = new MyLogger();
dependencies
"dependencies": {
"@nestjs/common": "^10.3.2",
"@nestjs/core": "^10.4.4",
"@nestjs/platform-express": "^10.4.4",
"@prisma/client": "5.22.0",
"nestjs-cls": "^4.4.1",
"reflect-metadata": "^0.2.1",
"rxjs": "^7.8.1",
"uuid": "^11.0.2"
},
result
traceId is lost when the sql is printed!!
Papooch commented
Seems to be a bug in Prisma, please see prisma/prisma#20104 and prisma/prisma#23397.
Unfortunately, there's nothing I can do on the library's side to fix this.