【发布时间】:2019-11-09 04:06:51
【问题描述】:
我和我的团队在几天内陷入沉思,以找出在开发期间编写调试级日志的正确位置。
我们使用winston 和winston-daily-rotate-file 来解耦部分日志记录过程,以及nest-winston,这是winston 记录器的嵌套模块包装器。
我们决定通过扩展内置的 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);
}
}),
);
}
}
在打印出调试日志之前,检查环境是否处于开发中对我来说有点难看。
如果上面使用拦截器的方法可能完全错误怎么办?
我怎样才能更好地解决这个问题?
【问题讨论】:
标签: typescript express logging nestjs