yan's Handicraft

作成したフリーソフトを公開
Home » PC/システム開発 » Scalatra でアクセスログとエラーログを出力したい

Scalatra でアクセスログとエラーログを出力したい

5月 22nd, 2013 Posted in PC/システム開発, scala, Scalatra

開発していると、必ずと言っていいぐらい、「アクセスログ」や「異常発生時のログ」の出力
を求められるので、Scalatra ではどうやったらいいのかやってみました。

  • org.scalatra.ScalatraServlet#serviceHttpServlet#service をオーバーライドして
    handle メソッドを呼び出す実装になっていたので、handle メソッドオーバーライドしてあげれば
    ログが統一的に出力でるのではないかと思いやってみました。

    • 結果
      • アクセスログは出力できるのですが、例外がキャッチできず、異常発生時のログが出力できませんでした。
        ソースを追いかけてみると、handle メソッド処理中に例外が発生すると、
        所々で例外をキャッチしていました。
  • 更にソースを読むと変数org.scalatra.ScalatraBase#errorHandler が、例外が発生時の
    処理に使われているのが分かりました。
    変数errorHandlerを書き換えてやると、異常時にログが出力できました。

    • 特記事項
      • errorHandler の型は type ErrorHandler = PartialFunction[Throwable, Any]
        という風に定義されています
      • Googleグループ scalatra-user でこの辺のことを議論されているスレッドがありました。==>
        “Logging exceptions”

実装例

テンプレートとして作成される ????Stack クラスに、以下のような感じで実装してみました

  errorHandler = {
    case rt: RuntimeException => {
      log.error("システムエラー発生 (RuntimeException) Path=:" + Option(request).fold("")(_.getRequestURI) +
        "\n  ErrorMessage=" + rt.getMessage, rt)
      status = HttpServletResponse.SC_BAD_REQUEST
      "Exception occured!"
    }

    case rt: Throwable => {
      log.error("システムエラー発生 (RuntimeException以外) :\n  ErrorMessage=" + rt.getMessage, rt)
      throw rt
    }
  }

  override def handle(req: HttpServletRequest, res: HttpServletResponse): Unit = {
    val path = req.getRequestURI
    val startMillis = System.currentTimeMillis()
    log.info( """[AccessLog] Path={}""", path)
    try {
      super.handle(req, res)
    } finally {
      val elapsedMillis = System.currentTimeMillis() - startMillis
      log.debug( """[EndLog]elapsedMillis={} ,Path={}""", elapsedMillis, path)
    }
  }

Leave a Reply

*