7
1

More than 3 years have passed since last update.

Nest.js + log4js ~標準 Logger を log4js で実装~

Last updated at Posted at 2020-04-07

目的

Nest.jslog4js を使う方法をまとめました。
次の内容を実装します。

事前準備

プロジェクトは Nest.js のCLIコマンドで生成します。

npm i -g @nestjs/cli
nest new logger-sample

以後、 標準テンプレートのプロジェクト をカスタマイズして実装していきます。

log4js をインストール

npm i --save log4js

標準 Logger を log4js で実装

公式ドキュメントにやり方は書いてあります。 Nest.js-TECHNIQUES-Logger

LoggerServiceを実装

標準 Logger を書き換えるために LoggerService を実装します。

logger-sample/src/logger/logger.service.ts
import { LoggerService, Injectable, Scope } from '@nestjs/common';
import { Logger } from 'log4js';

@Injectable({ scope: Scope.TRANSIENT })
export class CustomLogger implements LoggerService{

    constructor(private readonly logger: Logger) {}

    log(message: any, context?: string) {
        this.logger.log(message,context? context : '');
    }
    error(message: any, trace?: string, context?: string) {
        this.logger.error(message,trace? trace : '',context? context : '');
    }
    warn(message: any, context?: string) {
        this.logger.warn(message,context? context : '');
    }
    debug?(message: any, context?: string) {
        this.logger.debug(message,context? context : '');
    }    
}
  • リクエスト毎に出力情報は変わるため、スコープは TRANSIENT にしています。
  • log4jsLogger はコンストラクタから渡すようにしました。
  • verbose() は使わないため実装していません。

LoggerModule を実装

CustomLogger を公開するために LoggerModule を実装します。

logger-sample/logger/logger.module.ts
import { Module } from "@nestjs/common";
import { CustomLogger } from './logger.service';
import {configure,getLogger} from 'log4js';

const config = {
    "appenders":{
        "access":{
            "type": "file",
            "filename": "log/trace.log",
            "maxLogSize": 10485760,
            "category": "access",
            "layout": {
              "type": "pattern",
              "pattern": "[%d{yyyy/MM/dd hh.mm.ss.SSS}],[%p],[%X{ip}],[%X{method} %X{uri}],[%X{file} %X{line}:%X{column} %X{function}],%m"
            }
        },
        "console":{
            "type": "stdout",
            "layout": {
              "type": "pattern",
              "pattern": "[%d{yyyy/MM/dd hh.mm.ss.SSS}],[%p],[%X{ip}],[%X{method} %X{uri}],[%X{file} %X{line}:%X{column} %X{function}],%m"
            }
        }
    },
    "categories": {
        "default":{
            "appenders": ["access","console"],
            "level": "INFO"
        }
    }
}

const loggerFactory = {
    provide:CustomLogger,
    useFactory:()=>{
        configure(config);
        return new CustomLogger(getLogger("default"));
    }
}

@Module({
    providers:[loggerFactory],
    exports:[loggerFactory]
})
export class LoggerModule {}
  • configlog4js の設定情報です。次の設定をしています。
    • ファイル(logger-sample/log/trace.log)と標準出力にログを出力する。
    • リクエスト、スタック情報を追加したログフォーマットに変更
  • loggerFactory はカスタムインスタンスを作成する方法です。 詳しくは 公式 を参照してください。

LoggerModule を AppModule にインポートする。

importsLoggerModule を追加するだけです。

logger-sample/src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { LoggerModule } from './logger/logger.module';

@Module({
  imports: [LoggerModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Nest の標準 Logger を無効化して log4js を設定

main.ts を変更して、標準 Logger の無効化と CustomLogger を設定します。

logger-sample/src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { CustomLogger } from './logger/logger.service';

async function bootstrap() {
  const app = await NestFactory.create(AppModule,{logger:false});
  app.useLogger(app.get(CustomLogger));
  await app.listen(3000);
}
bootstrap();

app.service.ts で実際に log4js でログ出力を記述します。

logger-sample/src/app.service.ts
import { Injectable } from '@nestjs/common';
import { CustomLogger } from './logger/logger.service';

@Injectable()
export class AppService {

  constructor(private logger: CustomLogger){}

  getHello(): string {
    this.logger.error('Hello World!!');
    return 'Hello World!';
  }
}
  • constructorCustomLogger を注入します。
  • getHello()this.logger.error('Hello World!!'); でログ出力しています。

実際に動かした結果

13:28:05 - Found 0 errors. Watching for file changes.
[2020/04/07 13.28.06.101],[INFO],[null],[null null],[null null:null null],RoutesResolver
[2020/04/07 13.28.06.106],[INFO],[null],[null null],[null null:null null],RouterExplorer
[2020/04/07 13.28.06.108],[INFO],[null],[null null],[null null:null null],NestApplication
[2020/04/07 13.28.09.370],[ERROR],[null],[null null],[null null:null null],Hello World!! 

null が多いですが、後の実装で設定しておくのでひとまずOK

これで標準 Loggerlog4js に置き換えることができました。

次は ミドルウェアでリクエスト情報をログに追加

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1