NestJS:在调试级别最适合写日志的位置在哪里?

时间:2019-06-27 07:16:10

标签: typescript express logging nestjs

我和我的团队沉迷了几天,以找出在开发期间编写调试级别日志的正确位置。

我们正在使用winstonwinston-daily-rotate-file来解耦日志记录过程的一部分,并使用nest-winston(用于Winston logger的嵌套模块包装器)来分离。

我们决定通过扩展内置的Logger类来创建灵活的自定义记录器,作为服务。

@Injectable()
export class LoggerService extends Logger {
  constructor(
    @Inject('winston')
    private readonly logger: winston.Logger,
  ) { super(); }

 info(message: string, context?: string): void {
   this.logger.info(message, { context });
   super.log(message, context);
  }

 debug(message: string, context?: string): void {
   // To delegate the call to the parent class, no winston used.
   super.debug(message, context);
  }

 error(message: string, trace: string, context?: string): void {
   this.logger.error(message, { context });
   super.error(message, trace, context);
  }
}

您可能已经从方法debug()中注意到,存储设备(Transports)尚未故意在调试级别进行配置。我们希望仅在开发中通过控制台将它们打印出来。

现在,我们可以在相同上下文中的任何地方使用LoggerService。例如,

@Controller('users')
export class UsersController {
  constructor(private readonly logger: LoggerService) {}

}

@Injectable()
export class UsersService {
  constructor(private readonly logger: LoggerService) {}

  // Inside a method, debug some logic.
  this.logger.debug(message, UsersService.name);
}

这种方法一目了然,但是当代码被其他地方过度使用时,可能会变得非常混乱。

基于这个原因,我们认为应该在一个共享的位置上处理调试过程,并提出了一个让拦截器处理工作的想法。

import { LoggerService } from '../../logger/logger.service';

@Injectable()
export class DebuggingInterceptor implements NestInterceptor {
  constructor(private readonly logger: LoggerService) {}

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const ctx = `${context.getClass().name} ➜ ${context.getHandler().name}()`;

    return next
      .handle()
      .pipe(
        tap((response) => {
          if (process.env.NODE_ENV === 'development') {
            this.logger.debug(response, ctx);
          }
        }),
      );
  }
}

在打印调试日志之前,检查环境是否在开发中对我来说有点难看。

如果上面使用拦截器的方法可能完全错误,我会担心吗?

如何更好地解决此问题?

1 个答案:

答案 0 :(得分:0)

我认为使用拦截器的方法很好。如果您不喜欢在拦截器中检查环境的想法,则可以随时在LoggerService类中检查环境,以决定是否调用super.debug()方法,那样您就可以致电this.logger.debug(response, ctx)

作为旁注,我正在开发自己的版本的记录器,并尝试将类名注入记录器中,以便在记录器中设置上下文并从那里使用它,但这需要一些时间。只是对另一个想法的想法。