You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:46:14