4

ログ エントリで、ログ メソッドが呼び出された関数名をログに記録したいと考えています。

これは、ログ エントリを関数名で自動的にフィルタリングできるようにするためです。これは可能ですか?ライブラリはありますか?既存のライブラリの拡張機能はありますか?

言い換えれば、実行コンテキストが実行時に現在実行しているscala関数の名前を抽出することは可能ですか?

二次的な質問: これは大げさかもしれませんが、理想的には、scala が暗号化された名前を生成する実際の無名関数ではなく、ロギング呼び出しを含む最も近い名前付き関数が優先されます。後者はログから読み取るのが難しいでしょう。

4

1 に答える 1

2

これがあなたが使うことができるハックです。現在のスタックトレースをトラバースして、最初の非匿名関数を見つけます。

def printStackFrame() {
  /* Get current stack trace. The first frame is this method call. */
  val st = new RuntimeException().getStackTrace.view.drop(1)

  // st take(5) foreach println /* Print a few frames of interest */

  val name =
    st.map(ste => ste.getClassName + "." + ste.getMethodName)
      .dropWhile(_.matches(""".*anonfun\$\d*\.apply\$mcV\$sp$"""))
      .apply(0)

  println(name)
}

次のように使用できます。

class MyClass {
  def mydef() {
    printStackFrame()
  }

  def myhof(f: () => Unit) {
    f()
  }
}

val mc = new MyClass
mc.mydef() // Main$$anon$1$MyClass.mydef
mc.myhof(mc.mydef) // Main$$anon$1$MyClass.mydef
mc.myhof(() => {printStackFrame()}) // Main$$anon$1$MyClass.myhof

明らかな欠点は、その脆弱性です。上記の単一の正規表現で、匿名またはその他の興味深い機能をすべて無視するのに十分かどうかは、まったくわかりません。また、たとえそうであっても、将来のScalaバージョンでネーミングスキーマが変更されないという保証はありません。

于 2013-03-19T09:20:09.283 に答える