winstonでexpressのリクエストログを扱う

expressにおけるリクエストのロギングはmorganを使うのが鉄板ですが、winstonなどの他の高機能なロガーで、まとめてログを扱いたいことが多いと思います。

この記事では、どのようにしてそれを実現するのかを簡単な例で説明します。

準備

空のディレクトリを作成し、以下のようにしてexpress, morgan, winstonをインストールします。

$ npm install express morgan winston

コード

ルートが/のみの簡単なサーバーを例にとることにします。

具体的には以下のようなことをしています。

  • loggerという名前のwinstonのロガーインスタンスを作成
  • morganでリクエストログを(文字列の状態で)winstonに流し込むように
  • ステータスコード200を返すだけのルートを作成
  • ポート3000でリクエストを受け付けるように
const express = require('express');
const morgan = require('morgan');
const winston = require('winston');

const logger = winston.createLogger({
  transports: [
    new winston.transports.Console(),
  ],
});

const app = express();

app.use(morgan('tiny', {
  stream: {
    write: message => logger.info(message.trim()),
  },
}));

app.get('/', (req, res) => {
  res.sendStatus(200);
});

app.listen(3000);

確認

上のコードをindex.jsとして保存し、以下のコマンドでサーバーを立ち上げます。

$ node index.js

curlでリクエストを送ってみます。

$ curl http://localhost:3000/
OK

サーバーのアプリケーションの標準出力に以下のように出力されているはずです。うまくいっていることがわかります。

{"message":"GET / 200 2 - 3.712 ms","level":"info"}