我可以使用这个来完成这个工作:
scala> object LOGGER {
| def warning(msg: String)(implicit className:String) = {
| className
| }
| }
defined object LOGGER
scala> class testing {
| lazy implicit val className = this.getClass.getName
| def test = LOGGER.warning("Testing")
| }
defined class testing
scala> val obj = new testing()
obj: testing = testing@11fb4f69
scala> obj.test
res51: String = testing <=======
scala> class testing2 {
| lazy implicit val className = this.getClass.getName
| def test = LOGGER.warning("Testing")
| }
defined class testing2
scala> val obj2 = new testing2()
obj2: testing2 = testing2@2ca3a203
scala> obj2.test
res53: String = testing2 <=====
Run Code Online (Sandbox Code Playgroud)
我还尝试在 中使用 Thread.currentThread.getStackTraceobject LOGGER但无法让它打印函数testing中的调用类warning。还有其他方法可以做到这一点吗?
一种方法是DymamicVariable
import scala.util.DynamicVariable
object LOGGER {
val caller = new DynamicVariable[String]("---")
def time = new Date().toString
def warning(msg: String) = println(s"[${caller.value} : $time] $msg")
}
trait Logging {
def logged[T](action: => T) = LOGGER.caller.withValue(this.getClass.getName)(action)
}
class testing extends Logging {
def test = logged {
//some actions
LOGGER.warning("test something")
//some other actions
}
}
val t = new testing
t.test
Run Code Online (Sandbox Code Playgroud)
会打印类似的东西
[测试:11 月 25 日星期三 11:29:23 MSK 2015] 测试一些东西
或者不用混合也Logging可以直接使用
class testing {
def test = LOGGER.caller.withValue(this.getClass.getName) {
//some actions
LOGGER.warning("test something")
//some other actions
}
}
Run Code Online (Sandbox Code Playgroud)
另一种更强大但更复杂的支持方法是构建一些简单的宏
您可以在其他源中定义,最好在其他子项目中定义
import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros
class LoggerImpl(val c: Context) {
import c.universe._
def getClassSymbol(s: Symbol): Symbol = if (s.isClass) s else getClassSymbol(s.owner)
def logImpl(msg: Expr[String]): Expr[Unit] = {
val cl = getClassSymbol(c.internal.enclosingOwner).toString
val time = c.Expr[String](q"new java.util.Date().toString")
val logline = c.Expr[String](q""" "[" + $cl + " : " + $time + "]" + $msg """)
c.Expr[Unit](q"println($logline)")
}
}
object Logger {
def warning(msg: String): Unit = macro LoggerImpl.logImpl
}
Run Code Online (Sandbox Code Playgroud)
现在您不需要更改测试类:
class testing {
def test = {
//some actions
Logger.warning("something happen")
//some other actions
}
}
Run Code Online (Sandbox Code Playgroud)
并查看所需的输出。
这可能是运行时堆栈自省的非常有效的替代方案
| 归档时间: |
|
| 查看次数: |
3482 次 |
| 最近记录: |