NestJS 中如何便捷的动态设置自定义日志函数的 作用域参数 Nodejs
问一下各位大佬 我如果想以以下的方式去使用 LoggerService ,并且需要传递参数,是不是只能在 module 文件里面 provide 使用 useValue 。 因为我已经把 Logger 设置成了全局模块了,感觉要是继续在 provide 使用 useValue 就感觉没做全局一样,有没有其它方式能处理这个传参,比如使用个注解之类的,有没有比较好的方法? 我就暑假这两天看了一下 nestjs 的文档,想看看上面的问题能不能就使用 nest 的一些特性去解决,有大佬给个思路也行
// user.service.ts
[@Injectable](/user/Injectable)()
export class UserService {
constructor(private readonly logger: LoggerService) {}
}
// user.module.ts
@Module({
controllers: [UserController],
providers: [
UserService,
{
provide: LoggerService,
useValue: new LoggerService(‘user’),
},
],
})
export class UserModule {}
// src/app.module.ts
import { Module } from '[@nestjs](/user/nestjs)/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { UserModule } from './user/user.module'
import { LoggerModule } from './libs/logger/logger.module'
[@Module](/user/Module)({
imports: [UserModule, LoggerModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
// src/libs/logger/logger.module.ts
import { Global, Module } from '[@nestjs](/user/nestjs)/common'
import { LoggerService } from './logger.service'
[@Global](/user/Global)()
[@Module](/user/Module)({
providers: [LoggerService],
exports: [LoggerService],
})
export class LoggerModule {}
// src/libs/logger/logger.service.ts
import { ConsoleLogger, Injectable, Scope } from '[@nestjs](/user/nestjs)/common'
import { Signale } from 'signale'
[@Injectable](/user/Injectable)({ scope: Scope.TRANSIENT })
export class LoggerService extends ConsoleLogger {
private readonly logger: Signale
private readonly scope: string
constructor(scope = 'app') {
super()
this.logger = new Signale({
stream: process.stdout,
disabled: false,
interactive: false,
})
this.scope = scope
this.logger.scope(this.scope)
this.logger.config({
displayTimestamp: true, // 以 HH:MM:SS 的格式显示当前本地时间。
displayDate: true, // 以 YYYY-MM-DD 的格式显示当前本地日期。
displayFilename: false, // 显示记录器消息来源的文件名。
})
}
complete(message: string, ...args: any[]) {
this.logger.complete(message, ...args)
}
}
NestJS 中如何便捷的动态设置自定义日志函数的 作用域参数 Nodejs
总感觉要是写一个模块,就得 provide 一次,那 100 个 service 就得导入 100 次,这种比较重复性的工作感觉没必要
不传参,暴露一个方法去动态设置也行,不过我就是想知道 nestjs 有没有什么特性能解决这个问题,毕竟初学想了解一下😊
也可以在 LoggerModule 上 providers 多个 LoggerService ,如:AppLoggerService, OtherLoggerService…, 这样可以不用使用 useValue 吧
我目前是直接用了 ,然后在 app.module 中全局注册了,看着大佬你这个写法,我的疑惑点还是有的,就是我的 logger 构造器里面有个参数,这个参数怎么传
可能大佬没回复到我想要的点上,举个简单的例子,我有 a ,b ,c ,d 四个模块,logger 已经全局注册了,就是想 a,b,c,d 在使用 logger 的时候给构造器传递一个参数,我目前只知道在 provides 里面去引入 logger 然后使用 useValue 传参
#8 ok ,谢谢大佬
没太理解你的意思,不过看你需求,直接在类里面 new 一个 Logger 就好了好像。<br>import { Injectable, Logger } from 'nestjs/common';<br><br>()<br>export class XService implements OnModuleInit {<br><br> private readonly logger = new Logger(<a target="_blank" href="http://XService.name" rel="nofollow noopener">XService.name</a>);<br><br>
想着使用一下 nestjs 的特性来完成这个事情,在类里面 new 一下这个就没用上 nestjs 的特性了
#11 不是,在 app.useLogger 注入你的自定义 logger 不就可以了?
app.useLogger(app.get(XXLogger))
或者 Logger.overrideLogger(moduleRef.get(XXLogger))
然后直接 new Logger(XXService.name)
谢谢了,我知道怎么弄了
感觉楼主更想要一个工厂函数,根据不同的参数创建,或者根据当前的 module 的情况创建。
#15 是这么个感觉了,就是 logger 已经是全局了,我只用在 service 模块的构造器中
constructor(private readonly logger: LoggerService)
主要就是那个 scope 的参数传递,想用 nestjs 的特性去实现一下,因为是初学 nest 想折腾一下
不折腾我完全可以暴露一个 setScope 方法来动态设置
比如 (目前我是这么做了)看到 ConsoleLogger 里面也是实现了一个 setContext
constructor(private readonly logger: LoggerService) {
this.logger.setScope(service.name)
}
这样
又或者是直接导入 new 了传参也是可行
https://imgur.com/a/fntkmtP
图片发不出来??
没错没错,就是这种差不多
在 NestJS 中动态设置自定义日志函数的作用域参数,你可以利用 NestJS 内置的 Logger 服务,并结合依赖注入(DI)系统来实现。以下是一个示例,展示如何在 NestJS 中实现这一点:
首先,创建一个自定义的日志服务,继承自 NestJS 的 Logger 类:
import { Injectable, LoggerService } from '@nestjs/common';
@Injectable()
export class CustomLogger extends LoggerService {
log(message: string, context?: string) {
const scopedMessage = `[${context || 'DEFAULT_CONTEXT'}] ${message}`;
console.log(scopedMessage);
}
// 实现其他日志方法...
error(message: string, trace?: string, context?: string) {
const scopedMessage = `[${context || 'DEFAULT_CONTEXT'}] ${message}`;
console.error(scopedMessage, trace);
}
// 可以继续实现 warn, debug, verbose 等方法...
}
然后,在你的模块中提供这个自定义日志服务:
import { Module } from '@nestjs/common';
import { CustomLogger } from './custom-logger.service';
@Module({
providers: [
{
provide: LoggerService,
useClass: CustomLogger,
},
],
})
export class AppModule {}
现在,在你的服务或控制器中注入 LoggerService
,并动态设置上下文:
import { Injectable, Inject, LoggerService } from '@nestjs/common';
@Injectable()
export class SomeService {
constructor(@Inject(LoggerService) private readonly logger: LoggerService) {}
someMethod() {
this.logger.log('This is a log message', 'SomeContext');
}
}
这样,你就可以在 NestJS 中动态设置自定义日志函数的作用域参数了。