コンテンツにスキップ

NestJS でロガーを実装する

1
2
$ npx nest g module Logger
$ npx nest g service Logger
src/logger/logger.module.ts
1
2
3
4
5
6
7
8
import { Module } from "@nestjs/common";
import { LoggerService } from "./logger.service";

@Module({
  providers: [LoggerService],
  exports: [LoggerService],
})
export class LoggerModule {}
src/logger/logger.service.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import {
  LoggerService as ILoggerService,
  Injectable,
  LogLevel,
} from "@nestjs/common";

@Injectable()
export class LoggerService implements ILoggerService {
  private levels: LogLevel[] = [];

  log(message: any, ...optionalParams: any[]) {
    this._log("log", message, ...optionalParams);
  }

  error(message: any, ...optionalParams: any[]) {
    this._log("error", message, ...optionalParams);
  }

  warn(message: any, ...optionalParams: any[]) {
    this._log("warn", message, ...optionalParams);
  }

  debug?(message: any, ...optionalParams: any[]) {
    this._log("debug", message, ...optionalParams);
  }

  verbose?(message: any, ...optionalParams: any[]) {
    this._log("verbose", message, ...optionalParams);
  }

  fatal?(message: any, ...optionalParams: any[]) {
    this._log("fatal", message, ...optionalParams);
  }

  setLogLevels?(levels: LogLevel[]) {
    this.levels = levels;
  }

  private _log(level: LogLevel, message: any, ...optionalParams: any[]) {
    if (!this.levels.includes(level)) {
      return;
    }
    if (level === "log") {
      console.log(message, ...optionalParams);
    } else if (level === "error") {
      console.error(message, ...optionalParams);
    } else if (level === "warn") {
      console.warn(message, ...optionalParams);
    } else if (level === "debug") {
      console.debug(message, ...optionalParams);
    } else if (level === "verbose") {
      console.log(message, ...optionalParams);
    } else if (level === "fatal") {
      console.error(message, ...optionalParams);
    }
  }
}
src/app.module.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import { LogLevel, Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { TypeOrmModule } from "@nestjs/typeorm";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { LoggerModule } from "./logger/logger.module";
import { LoggerService } from "./logger/logger.service";
import { Todo } from "./todos/entities/todo.entity";
import { TodosModule } from "./todos/todos.module";
import { User } from "./users/entities/user.entity";
import { UsersModule } from "./users/users.module";
import { UsersService } from "./users/users.service";

@Module({
  imports: [
    ConfigModule.forRoot(),
    TypeOrmModule.forRoot({
      type: "mysql",
      host: process.env.DATABASE_HOST,
      port: parseInt(process.env.DATABASE_PORT),
      username: process.env.DATABASE_USERNAME,
      password: process.env.DATABASE_PASSWORD,
      database: process.env.DATABASE_NAME,
      entities: [Todo, User],
      synchronize: true,
    }),
    TodosModule,
    UsersModule,
    LoggerModule, // ★
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  constructor(
    private readonly usersService: UsersService,
    private readonly loggerService: LoggerService
  ) {}

  async onModuleInit() {
    console.log("onModuleInit");
    const users = await this.usersService.findAll();
    if (users.length <= 0) {
      console.log("Create admin");
      await this.usersService.create({ name: "admin" });
    }
    this.loggerService.setLogLevels(
      // ★
      process.env.LOG_LEVELS.split(",").map((l) => l as LogLevel)
    );
    this.loggerService.log("Hello");
  }
}