我可以使用这个来完成这个工作:
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 <=====
我还尝试在中使用 Thread.currentThread.getStackTraceobject LOGGER
但无法让它打印调用类testing
in the warning
功能。
还有其他方法可以做到这一点吗?
动态变量
一种方法是动态变量 http://www.scala-lang.org/api/current/index.html#scala.util.DynamicVariable
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
会打印类似的东西
[测试: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
}
}
Macro
另一种更强大但更复杂的支持方法是构建一些简单的macro http://docs.scala-lang.org/overviews/quasiquotes/intro.html
您可以在其他源中定义,最好在其他子项目中定义
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
}
现在您不需要更改测试类:
class testing {
def test = {
//some actions
Logger.warning("something happen")
//some other actions
}
}
并查看所需的输出。
这将是运行时堆栈自省的高性能替代方案
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)