nestjs 功能之:🐉日志 logger

logger 是 nestjs 内置的功能。看看怎么使用,以及如何自定义 logger。markdown

开启/关闭 logger 的显示

  1. 咱们在建立一个 app 的时候,咱们就可在 create 参数添加第二参数,来配置 logger
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> {}
复制代码
  • NestApplicationOptions 继承子 NestApplicationContextOptions
export class NestApplicationContextOptions {
  logger?: LoggerService | LogLevel[] | boolean;
}
复制代码

logger 级别:

  • 'log'
  • 'error'
  • 'warn'
  • 'debug'
  • 'verbose'。
// 层次类型
export type LogLevel = 'log' | 'error' | 'warn' | 'debug' | 'verbose';

// 建立app时使用配置 logger 层次
const app = await NestFactory.create(ApplicationModule, {
  logger: ['error', 'warn'],
});
await app.listen(3000);
复制代码

LoggerService 接口

咱们要实现自定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) {}
}
复制代码

扩展示有 logger

扩展 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) {}
}
复制代码

logger模块

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属性传递给@Injectable()装饰器选项对象来指定注入范围

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

第三方 logger

生产应用程序一般具备特定的日志记录要求,包括高级筛选,格式化和集中式日志记录。Nest的内置记录器用于监视Nest系统的行为,而且在开发过程当中也可用于功能模块中的基本格式化文本记录,可是生产应用程序一般会利用Winston等专用记录模块。与任何标准Node.js应用程序同样,您能够在Nest中充分利用此类模块。日志

相关文章
相关标签/搜索