通过扩展 NestJS 中的默认记录器来实现自定义记录器时遇到问题。我遵循文档https://docs.nestjs.com/techniques/logger#using-the-logger-for-application-logging。
import { Injectable, Logger, Scope } from '@nestjs/common';
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerService extends Logger {
votes = 0;
debug(message: string, trace?: string) {
super.debug(message, trace);
}
error(message: string, trace?: string) {
super.error(message, trace);
}
log(message: string, trace?: string) {
this.votes = this.votes + 1;
console.log(this.votes, 'log', message);
super.log(message, trace);
}
verbose(message: string, trace?: string) {
super.verbose(message, trace);
}
warn(message: string, trace?: string) {
super.warn(message, trace);
}
}
并在 main.ts 中
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { AllExceptionsFilter } from './shared/exception-filters/all-exception-filters';
import { LoggerService } from './shared/modules/logger/logger.service';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: false,
});
app.useLogger(new LoggerService());
app.useGlobalFilters(new AllExceptionsFilter());
await app.listen(3000);
}
bootstrap();
在我的控制器中
Controller('user')
export class UserController {
constructor(private readonly userService: UserService, private logger: LoggerService) {}
@Get('/logger-example')
getLoggerExample() {
this.logger.log('it works ?');
return 'loggerExample';
}
当然用户模块导入记录器模块。
我对该记录器有两个问题:
第一个:
当我点击
user/logger-example
时,我从记录器那里得到了两次日志。看起来来自 main.ts
的记录器恰好是 app.useLogger(new LoggerService());
与注入的实例一起执行,将来我想放置一些异步记录器,如 pino 或其他东西,我担心日志将被发送两次。我认为我的配置有问题,因为它看起来不像常见问题。从默认记录器中我得到了正确的一条消息。
第二个:
如果我也将该服务注入到不同的模块,例如支付。并为用户设置了相同的端点,Logger 类上的投票字段始终为 0。对于瞬态注入范围来说,这是正确的行为吗?因为据我了解,它应该按模块注入。因此,在一个模块中,不应重置计数器。
配置是否正确?或者这是正常行为?我真的很担心两个记录器在一个中执行
this.logger.log
。
我发现,传递到 super.log 的所有元素都被迫成为另一个日志行。因此,重复的日志来自 super.log 中的两个参数。请仅转发消息。
log(message: string) {
this.votes = this.votes + 1;
console.log(this.votes, 'log', message);
super.log(message);
}
这是我如何编写我的方法来停止双重记录:
@Injectable()
export class LoggerCustomService extends ConsoleLogger {
error(message: any, stack?: string, context?: string) {
if (stack) {
super.error(stack, context);
} else {
super.error(message, context);
}
}
log(message: any, context?: string) {
super.log(message);
}
fatal(message: any, context?: string) {
super.fatal(message);
}
warn(message: any, context?: string) {
super.warn(message);
}
debug(message: any, context?: string) {
super.debug(message);
}
verbose(message: any, context?: string) {
super.verbose(message);
}
}
将上下文传递给 super() 会导致双重日志,并且当我在被调用服务中设置记录器的上下文时不需要。示例:
constructor(private readonly loggerCustomService: LoggerCustomService) {
this.loggerCustomService.setContext('DevLoggerController');
}
对于错误方法,如果存在堆栈,我必须删除消息。这样,两种方法都有效:
this.loggerCustomService.error('Error to loooog');
和
try {
throw new Error('plante');
} catch (e) {
this.loggerCustomService.error(e, e.stack);
}