Nestjs Winston模块,提供灵活的日志记录方式。
参考自 nest-winston
安装
npm install --save nest-winston-module winston
快速开始
导入 WinstonModule
至 nest应用的根module
(通常是AppModule
),并使用forRoot()
方法来配置nest-winston-module
. 创建参数与winston.createLogger方法所需的参数一致,可参考winston
官方文档:createLogger()
import { Module } from '@nestjs/common';
import { WinstonModule } from 'nest-winston-module';
import * as winston from 'winston';
@Module({
imports: [
WinstonModule.forRoot({
// options
}),
],
})
export class AppModule {}
在此之后,我们便可以使用Winstontoken
将Winston
实例注入我们的nest
应用中去,
nest-winston-module
为应用的不同模块提供了一个token枚举,从而使处理不同类型的日志更加容易。看看下边这个示例:
enum WinstonProviderEnum {
/**
* @description 替换 nest core Logger
*/
coreProvider = 'winstonCoreProvider',
/**
* @description 应用层级 level Logger
*/
appProvider = 'winstonAppProvider',
/**
* @description controller Logger
*/
controllerProvider = 'winstonControllerProvider',
/**
* @description graphQL resolver Logger
*/
resolverProvider = 'winstonResolverProvider',
/**
* @description service Logger
*/
serviceProvider = 'winstonServiceProvider',
/**
* @description 控制台 Logger
*/
consoleProvider = 'winstonConsoleProvider',
/**
* @description 所有Loggers的集合
*/
loggersProvider = 'winstonLoggersProvider',
}
这是在Nest Contrroler
中使用WinstonLogger的示例:
import { Controller, Inject } from '@nestjs/common';
import { WinstonProviderEnum, NestWinstonLogger } from 'nest-winston-module';
@Controller('cats')
export class CatsController {
// 使用提供的WinstonProviderEnum枚举来注入Winstoncontroller Logger至Cats Controller中去
constructor(@Inject(WinstonProviderEnum.controllerProvider) private readonly logger: NestWinstonLogger) { }
}
请注意,WinstonModule
是一个全局模块,它将在所有功能模块中可用。
Nest Async configuration(异步配置注入)
有时我们需要异步传递options,例如,当服务的启动依赖于动态配置项的读取。 在这种情况下,请使用forRootAsync()
方法,并从useFactory
方法返回一个选项对象:
import { Module } from '@nestjs/common';
import { WinstonModule } from 'nest-winston-module';
import * as winston from 'winston';
@Module({
imports: [
WinstonModule.forRootAsync({
useFactory: () => ({
// options, 后续会有配置示例
}),
inject: [],
}),
],
})
export class AppModule {}
useFactory
创建模块的步骤可能是异步的,我们可以使用inject
选项注入依赖项,并可以使用imports
选项导入其他模块。
另外,我们可以使用useClass
语法:
WinstonModule.forRootAsync({
useClass: WinstonConfigService,
})
使用上述代码,Nest
将创建一个新的WinstonConfigService
实例,并调用其方法createWinstonModuleOptions
以提供模块选项。
替换Nest Core Logger
除了应用程序层级的日志记录之外,nest-winston-module
还提供了WinstonLogger
定制实现,可与Nest
自带的日志记录系统一起使用。 以下是示例main.ts
文件:
import { WinstonProviderEnum } from 'nest-winston-module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useLogger(app.get(WinstonProviderEnum.coreProvider));
}
bootstrap();
NestApplication
实例上的get()
方法用于检索WinstonLogger
类的实例,该实例仍使用WinstonModule.forRoot
或WinstonModule.forRootAsync
方法进行配置。
注意,当我们替换Nest Core Logger时,只能使用WinstonProviderEnum.coreProvider
token来做替换。 因为Winston
与Nest
所遵循的Logger
接口并不完全相同,我们在框架内部对coreProvider
做了微妙的适配。
替换Nest Core Logger (并且用作启动服务实例)
使用如上方式有一个小缺点。 Nest
必须先引导应用程序(实例化模块和提供程序,注入依赖关系等),在此过程中,WinstonLogger
实例尚不可用,这意味着Nest
会退回到内部Logger
。
这里还有一种解决方案,是使用createLogger
函数在应用程序生命周期之外创建Logger
,并将其传递给NestFactory.create
:
import { WinstonModule } from 'nest-winston-module';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
logger: WinstonModule.createLogger({
// options (same as WinstonModule.forRoot() options)
})
});
}
bootstrap();
不过使用这种方式,我们便无法使用Nest
的依赖注入特性了。这意味着WinstonModule.forRoot
和WinstonModule.forRootAsync
方法么得用了。
要在我们的应用程序中也使用core Logger
,请看如下示例:
import { Logger, Module } from '@nestjs/common';
@Module({
providers: [Logger],
})
export class AppModule {}
import { Controller, Inject, Logger, LoggerService } from '@nestjs/common';
@Controller('cats')
export class CatsController {
constructor(@Inject(Logger) private readonly logger: LoggerService) { }
}
上述代码之所以可行,是因为Nest Logger
包装了我们的WinstonLogger
(由createLogger
方法返回的相同实例)并将所有调用转发给它。
配置
我们可以使用nest-winston-module
提供的默认配置项,或者根据业务的不同进行自定义操作:
import { Module } from '@nestjs/common';
import {
coreOptions,
appOptions,
controllerOptions,
resolverOptions,
serviceOptions,
consoleOptions,
} from 'nest-winston-module';
import * as winston from 'winston';
@Module({
imports: [
WinstonModule.forRoot({
core: coreOptions,
app: appOptions,
resolver: resolverOptions,
controller: controllerOptions,
service: serviceOptions,
console: consoleOptions,
directory: process.cwd() + '/logs',
}),
],
})
export class AppModule {}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!