logger 是 nestjs 内置的功能。看看怎么使用,以及如何自定义 logger。markdown
const app = await NestFactory.create(ApplicationModule, {
logger: false,
});
await app.listen(3000);
复制代码
源码:app
public async create<T extends INestApplication = INestApplication>(
module: any,
serverOrOptions?: AbstractHttpAdapter | NestApplicationOptions,
options?: NestApplicationOptions,
): Promise<T> {}
复制代码
export class NestApplicationContextOptions {
logger?: LoggerService | LogLevel[] | boolean;
}
复制代码
// 层次类型
export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose';
// 建立app时使用配置 logger 层次
const app = await NestFactory.create(ApplicationModule, {
logger: ['error', 'warn'],
});
await app.listen(3000);
复制代码
咱们要实现自定Logger必须实现 LoggerServiceasync
export interface LoggerService {
log(message: any, context?: string);
error(message: any, trace?: string, context?: string);
warn(message: any, context?: string);
debug?(message: any, context?: string);
verbose?(message: any, context?: string);
}
import { LoggerService } from '@nestjs/common';
export class MyLogger implements LoggerService {
log(message: string) {}
error(message: string, trace: string) {}
warn(message: string) {}
debug(message: string) {}
verbose(message: string) {}
}
复制代码
扩展 nestjs 的 logger 须要继承 nestjs 的 Logger 接口,而 Logger 是继承上面的 LoggerService 接口ide
import { Logger } from '@nestjs/common';
export class MyLogger extends Logger {
error(message: string, trace: string) {
super.error(message, trace);
}
}
复制代码
源码函数
@Injectable()
export class Logger implements LoggerService {
private static logLevels: LogLevel[] = [
'log',
'error',
'warn',
'debug',
'verbose',
];
private static lastTimestamp?: number;
private static instance?: typeof Logger | LoggerService = Logger;
constructor( @Optional() protected context?: string, @Optional() private readonly isTimestampEnabled = false, ) {}
error(message: any, trace = '', context?: string) {}
log(message: any, context?: string) {}
warn(message: any, context?: string) {}
debug(message: any, context?: string) {}
verbose(message: any, context?: string) {}
setContext(context: string) {}
static overrideLogger(logger: LoggerService | LogLevel[] | boolean) {}
static log(message: any, context = '', isTimeDiffEnabled = true) {}
static error( message: any, trace = '', context = '', isTimeDiffEnabled = true, ) {}
static warn(message: any, context = '', isTimeDiffEnabled = true) {}
static debug(message: any, context = '', isTimeDiffEnabled = true) {}
static verbose(message: any, context = '', isTimeDiffEnabled = true) {}
private callFunction( name: 'log' | 'warn' | 'debug' | 'verbose', message: any, context?: string, ) {}
private getInstance(): typeof Logger | LoggerService {}
private isLogLevelEnabled(level: LogLevel): boolean {}
private static printMessage( message: any, color: (message: string) => string, context = '', isTimeDiffEnabled?: boolean, ) {}
private static updateAndGetTimestampDiff(
isTimeDiffEnabled?: boolean,
): string {}
private static printStackTrace(trace: string) {}
}
复制代码
import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';
@Module({
providers: [MyLogger],
exports: [MyLogger],
})
export class LoggerModule {}
复制代码
同归依赖注入将 LoggerModule 注入都 AppModule 中,经过 app 的 get 方法来获取 MyLogger 的实例。app 也提供了 useLogger 来使用 Logger。ui
const app = await NestFactory.create(ApplicationModule, {
// 关闭系统日志
logger: false,
});
app.useLogger(app.get(MyLogger))
await app.listen(3000);
复制代码
这看起来彷佛有点麻烦,其实咱们能够直接创新一个实例,不使用 Module 的方式来注入。this
const app = await NestFactory.create(ApplicationModule, {
// 关闭系统日志
logger: false,
});
// 使用自定义日志
app.useLogger(new MyLogger());
await app.listen(3000);
复制代码
Scope 是枚举类型spa
export enum Scope {
/** * 提供程序能够在多个类之间共享。提供者生命周期 *与应用程序生命周期严格相关。一旦应用程序具备 *自举,全部提供程序都已实例化。 */
DEFAULT,
/** * 每次使用都会实例化提供者的新私有实例。 */
TRANSIENT,
/** * 为每一个请求处理管道实例化一个新实例 */
REQUEST,
}
复制代码
// scope选项做为Logger类的配置元数据,并指定一个临时范围,
// 以确保Logger在每一个功能模块中都有一个惟一的实例
import { Injectable, Scope, Logger } from '@nestjs/common';
@Injectable({ scope: Scope.TRANSIENT })
export class MyLogger extends Logger {}
import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service';
@Module({
providers: [MyLogger],
exports: [MyLogger],
})
export class LoggerModule {}
import { Injectable } from '@nestjs/common';
import { MyLogger } from './my-logger.service';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
constructor(private myLogger: MyLogger) {
this.myLogger.setContext('CatsService');
}
findAll(): Cat[] {
this.myLogger.warn('About to return cats!');
return this.cats;
}
}
const app = await NestFactory.create(ApplicationModule, {
logger: false,
});
app.useLogger(new MyLogger());
await app.listen(3000);
复制代码
使用做用域注入,能够每一个模块中都包含一个 logger 实例,咱们经过须要定义个单独的 Module 模块。在使用的的时候,咱们在服务中使用 MyLogger。最后咱们还须要在 app 须要调用 useLogger 来实例化 MyLogger 函数。debug
生产应用程序一般具备特定的日志记录要求,包括高级筛选,格式化和集中式日志记录。Nest的内置记录器用于监视Nest系统的行为,而且在开发过程当中也可用于功能模块中的基本格式化文本记录,可是生产应用程序一般会利用Winston等专用记录模块。与任何标准Node.js应用程序同样,您能够在Nest中充分利用此类模块。日志