web-dev-qa-db-ja.com

例外ロギングを試してください

ScalaのTryは非常に便利です。

そのパターンを使用したいのですが、すべての例外をログに記録します。

これどうやってするの?

24
SRobertJames

次のヘルパーを定義します。

_import scala.util.{Try, Failure}

def LogTry[A](computation: => A): Try[A] = {
  Try(computation) recoverWith {
    case e: Throwable =>
      log(e)
      Failure(e)
  }
}
_

その後、Tryを使用するのと同じように使用できますが、例外はlog(e)を介してログに記録されます。

31
sjrd

暗黙のクラスを使用してさらに微調整できます

def someMethod[A](f: => A): Try[A] = Try(f)

implicit class LogTry[A](res: Try[A]) {
  def log() = res match {
    case Success(s) => println("Success :) " + s); res
    case Failure(f) => println("Failure :( " + f); res
  }
}

これで、someMethodを呼び出すことができ、その結果で次のようにlogを呼び出すことができます。

scala> someMethod(1/0).log
Failure :( Java.lang.ArithmeticException: / by zero

そして

scala> someMethod(1).log
Success :) 1

もちろん、暗黙のクラス内のprintlnメソッドは、任意のロギングに置き換えることができます。

5
goral

開始Scala 2.13、連鎖操作 tap を使用して、元の値を返しながら、任意の値に副作用(この場合はログ)を適用できます。

import util.chaining._

val x = Try("aa".toInt).tap(_.failed.foreach(println))
// Java.lang.NumberFormatException: For input string: "aa"
// x: Try[Int] = Failure(Java.lang.NumberFormatException: For input string: "aa")

または同等のパターンマッチングバージョン:

val x = Try("aa".toInt).tap { case Failure(e) => println(e) case _ => }
// Java.lang.NumberFormatException: For input string: "aa"
// x: Try[Int] = Failure(Java.lang.NumberFormatException: For input string: "aa")

tap チェーン操作は、値(この場合はprintln)に副作用(この場合はTryまたはログ)を適用します。 tapが適用された元の変更されていない値(Try)を返します。

def tap [U](f:(A)=> U):A

2
Xavier Guihot