简体   繁体   English

将日志添加到Scala代码的工具

[英]Instrumentation to add logging to Scala code

In Java we can use AspectJ to add logging transparently to Java classes (or probably use other byte code instrumentation tools). 在Java中,我们可以使用AspectJ将日志透明地添加到Java类中(或者可能使用其他字节码检测工具)。 Now I wonder how to add logging transparently to Scala functions. 现在,我想知道如何将日志透明地添加到Scala函数中。

I would like a tool to transform a function foo 我想要一个转换函数foo的工具

def foo(x:Int) = x + 1

to something like that: 到这样的事情:

def foo(x:Int) = { 
   log.trace("Enter foo with x = " + x) // added automatically
   val r = x + 1
   log.trace("Exit foo with r = " + r) // added automatically  
   r
}

How would you add logging transparently to Scala functions? 您如何将日志记录透明地添加到Scala函数?

AspectJ will work just fine with Scala code. AspectJ将与Scala代码一起正常工作。 You'll just need to follow the Scala name mangling rules (ie def > becomes def $gt ) and so on. 您只需要遵循Scala名称修改规则(即def >变成def $gt ),依此类推。

Suppose you have 假设你有

class Foo {
  def foo(x: Int) {
  }
  def bar() { }
}

To add logging, you can use the Java AspectJ syntax, adding 要添加日志记录,可以使用Java AspectJ语法,添加

"org.aspectj" % "aspectjweaver" % "1.7.2",
"org.aspectj" % "aspectjrt" % "1.7.2"

To your build.sbt . 到您的build.sbt Moving on, you can have the following aspect: 继续,您可以具有以下方面:

@Aspect
public class MonitorAspect {

    @Pointcut(value = "execution (* your.package.Foo.*(..))")
    public void methodsInFoo() {}

    @Before("methodsInFoo()")
    public void enter(JoinPoint jp) {
        // log
    }

    @After("methodsInFoo()")
    public void exit(JoinPoint jp) {
    }
}

The final piece will be the META-INF/aop.xml , which defines the work for the load-time weaver: 最后一块是META-INF/aop.xml ,它定义了加载时织布工的工作:

<aspectj>

    <aspects>
        <aspect name="your.package.MonitorAspect"/>
    </aspects>

    <weaver options="-XnoInline">
        <include within="your.package.*"/>
    </weaver>

</aspectj>

Finally, start your JVM with -javaagent:$PATH_TO_ASPECTJWEAVER.JAR and you're all set. 最后,使用-javaagent:$PATH_TO_ASPECTJWEAVER.JAR启动JVM,一切-javaagent:$PATH_TO_ASPECTJWEAVER.JAR


In your case, it may be worth thinking about using higher-order functions. 就您而言,可能值得考虑使用高阶函数。 If you are using logging as just an example, and if you're actually doing something before and after some inner function, you should consider using HOFs. 如果仅以日志记录为例,并且实际上是某些内部函数之前之后执行某些操作,则应考虑使用HOF。

def logged[U](f: => U): U = {
    log.info("Before")
    val ret = f
    log.info("After")
    ret
}

Here, you have the logged function that takes another function f , deals with the logs and does whatever f does. 在这里,您具有带另一个函数flogged函数,该函数处理日志并执行f操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM