如何在NestJS的main.ts中调用自定义Winston日志服务?
在NestJS启动阶段使用自定义Winston日志服务替代console
我目前在NestJS应用启动时,通过NestFactory.create组装应用,现在用的是常规console来记录启动信息和捕获错误,想换成自己实现的Winston日志服务。
现有启动代码
const start = async () => { try { const PORT = process.env.PORT || 5000; const app = NestFactory.create(AppModule, { cors: true }); (await app).listen(PORT, () => { console.log(`server started on port ${PORT}`); }); } catch (error) { console.log(error); } }; start();
已实现的WinstonLoggerModule
@Module({}) export class WinstonLoggerModule { static forRoot(): DynamicModule { return { imports: [ WinstonModule.forRoot({ transports: [ new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp(), winston.format.ms(), nestWinstonModuleUtilities.format.nestLike('MyApp', { colors: true, prettyPrint: true, }), ), }), ], }), ], module: WinstonLoggerModule, providers: [ { provide: WINSTON_LOGGER_SERVICE, useClass: WinstonLoggerService }, ], exports: [WINSTON_LOGGER_SERVICE], }; } }
已实现的WinstonLoggerService
@Injectable() export class WinstonLoggerService implements IWinstonLoggerService { constructor( @Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger, ) {} warn(message): void { this.logger.warn(message); } error(message): void { this.logger.error(message); } debug(message): void { this.logger.debug(message); } info(message): void { this.logger.info(message); } }
解决方案
由于NestFactory.create是异步操作,容器初始化完成前无法直接通过依赖注入获取WinstonLoggerService,可以通过以下两种方式实现需求:
方式一:直接初始化Winston实例(不依赖Nest容器)
在启动文件中单独初始化Winston配置,直接用该实例记录启动阶段的日志和错误,无需依赖Nest模块加载:
import * as winston from 'winston'; import { nestWinstonModuleUtilities } from 'nest-winston'; // 提前初始化Winston日志实例 const logger = winston.createLogger({ transports: [ new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp(), winston.format.ms(), nestWinstonModuleUtilities.format.nestLike('MyApp', { colors: true, prettyPrint: true, }), ), }), ], }); const start = async () => { try { const PORT = process.env.PORT || 5000; const app = await NestFactory.create(AppModule, { cors: true }); await app.listen(PORT); logger.info(`server started on port ${PORT}`); } catch (error) { logger.error('应用启动失败', error); } }; start();
方式二:创建应用后从容器获取日志服务
如果必须使用Nest容器中的WinstonLoggerService,可以在应用创建完成后,从容器中获取该服务再记录启动信息:
const start = async () => { let app; try { const PORT = process.env.PORT || 5000; app = await NestFactory.create(AppModule, { cors: true }); // 从容器中获取自定义日志服务 const winstonLogger = app.get(WINSTON_LOGGER_SERVICE); await app.listen(PORT); winstonLogger.info(`server started on port ${PORT}`); } catch (error) { // 若应用创建失败,容器未初始化,此时降级用console或提前初始化的Winston实例记录错误 console.error('应用启动失败', error); } }; start();
注意事项
- 若
NestFactory.create执行失败,容器还未初始化,此时无法获取DI中的日志服务,建议提前单独初始化Winston实例来捕获这类启动错误。 - 确保
WinstonLoggerModule.forRoot()已在AppModule的imports中导入,否则无法从容器中获取WINSTON_LOGGER_SERVICE。
内容的提问来源于stack exchange,提问作者tresor13
相关产品推荐
相关产品推荐

