Nest.js + log4js ～ミドルウェアでリクエスト情報をログに追加～

# 目的

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

* [標準Loggerをlog4jsで実装](https://qiita.com/wakusan-6126/items/c03ae0866bad35a86a6c) (前回)
* [ミドルウェアでリクエスト情報をログに追加](https://qiita.com/wakusan-6126/items/f49ed378b9d05e907bad) (今回)
* [ログ出力時にスタック情報を追加](https://qiita.com/wakusan-6126/items/5cefc13c0aa12be7d3bd) (次回)


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

## CustomLoggerでリクエスト情報をセットする。

まず、 `CustomLogger` を修正してリクエスト情報をセットするメソッドを定義します。

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

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

    constructor(private readonly logger: Logger) {}

    setRequestInfo(req: Request){
        this.logger.addContext('ip',req.ip);
        this.logger.addContext('method',req.method);
        this.logger.addContext('uri',req.url);
    }

    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 : '');
    }    
}
```

* `setRequestInfo()` で `express` の `Request` からリクエスト情報を設定します。
* プロジェクト固有の出力情報(アクセストークンなど)がある場合はここに追加します。

## LoggerMiddleware を実装する。

`LoggerMiddleware` を実装してリクエスト情報をログに追加します。

``` logger-sample/src/logger/logger.middleware.ts
import { NestMiddleware, Injectable } from '@nestjs/common';
import { Request, Response } from 'express';
import { CustomLogger } from './logger.service';

@Injectable()
export class LoggerMiddleware implements NestMiddleware{
    constructor(private logger: CustomLogger){}
    use(req: Request, res: Response, next: Function) {
        this.logger.setRequestInfo(req);
        next();
    }
}
```

* `constructor()` で `CustomLogger` を注入します。
* `use()` で `Request` を `CustomLogger` に渡してリクエスト情報を設定します。

## AppModule に LoggerMiddleware を設定する。

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

@Module({
  imports: [LoggerModule],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(LoggerMiddleware)
      .forRoutes('');
  }
}
```

* `AppModuole` の `configure()` を実装して `LoggerMiddleware` を設定します。

実行結果

```
[2020/04/07 14.00.05.918],[INFO],[null],[null null],[null null:null null],RoutesResolver
[2020/04/07 14.00.05.922],[INFO],[null],[null null],[null null:null null],RouterExplorer
[2020/04/07 14.00.05.924],[INFO],[null],[null null],[null null:null null],NestApplication
[2020/04/07 14.00.09.129],[ERROR],[::1],[GET /],[null null:null null],Hello World!! 
```

標準ライブラリからの出力は相変わらず `null` ですが、リクエストからIP、メソッド、URI が出力されています。

次は、[ログ出力時にスタック情報を追加](https://qiita.com/wakusan-6126/items/5cefc13c0aa12be7d3bd)