morganでアクセスログを書き込みつつ、書き込み先を自前のロガーに変える #Node.js

Node.jsのサーバーでアクセスログ出してますか? morganを使って吐きましょう。

今回紹介するのはNuxt.jsで使う場合のものですが expressとかでも似たようなコードで対応できるはずです。

morganの書き込み先を自前のロガーに書き換える

毎回morganの関数を呼ばないといけないけど こんな感じになる。

import morgan from "morgan"

const format = morgan.compile(
  ":remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms" // もともとmorganにある short フォーマット
)

export default function(req, res, next) {
  const logger = req.logger // 後述のloggerのミドルウェアでいい感じのロガーを渡している
  morgan(format, {
    stream: {
      write(message) {
        logger.info(message.trim()) // 改行が後ろについてしまうのでtrim
      }
    }
  })(req, res, next)
}

このコードはNuxt.jsで使っています。Nuxtの場合は nuxt.config.jsでserverMiddlewareに指定してください。

おまけ: logger + RequestIdのミドルウェア

loggerのミドルウェアはこんな感じにしておいた。 RequestIdのミドルウェアと混ざってて良くない気はするけど。

import rootLogger from "./logger"
import uuidv4 from "uuid/v4"
import { getClientIp } from "request-ip"

export default function(req, res, next) {
  const requestId = uuidv4()
  const logger = rootLogger.child({
    req: {
      path: req.url,
      method: req.method,
      remoteIp: getClientIp(req),
      requestURI: req.originalUrl,
      requestURL: req.headers.host + req.originalUrl,
      userAgent: req.headers["user-agent"]
    },
    requestId
  })
  req.logger = logger
  res.setHeader("RequestId", requestId)
  next()
}