Инструментарий для добавления регистрации в код Scala
В Java мы можем использовать AspectJ
прозрачно добавить ведение журнала в классы Java (или, возможно, использовать другие инструменты инструментария байт-кода). Теперь мне интересно, как прозрачно добавить логирование в функции Scala.
Я хотел бы инструмент для преобразования функции foo
def foo(x:Int) = x + 1
к чему-то такому:
def foo (x: Int) = { log.trace ("Enter foo with x =" + x) // добавляется автоматически val r = x + 1 log.trace("Exit foo with r = " + r) // добавляется автоматически р }
Как бы вы прозрачно добавили логирование в функции Scala?
1 ответ
AspectJ будет прекрасно работать с кодом Scala. Вам просто нужно следовать правилам искажения имени в Scala (т.е. def >
становится def $gt
) и так далее.
Предположим, у вас есть
class Foo {
def foo(x: Int) {
}
def bar() { }
}
Чтобы добавить ведение журнала, вы можете использовать синтаксис Java AspectJ, добавив
"org.aspectj" % "aspectjweaver" % "1.7.2",
"org.aspectj" % "aspectjrt" % "1.7.2"
На ваш build.sbt
, Двигаясь дальше, вы можете иметь следующий аспект:
@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) {
}
}
Последний кусок будет META-INF/aop.xml
, который определяет работу для ткача времени загрузки:
<aspectj>
<aspects>
<aspect name="your.package.MonitorAspect"/>
</aspects>
<weaver options="-XnoInline">
<include within="your.package.*"/>
</weaver>
</aspectj>
Наконец, начните свою JVM с -javaagent:$PATH_TO_ASPECTJWEAVER.JAR
и все готово
В вашем случае, возможно, стоит подумать об использовании функций более высокого порядка. Если вы используете журналирование в качестве примера и действительно делаете что-то до и после какой-то внутренней функции, вам следует рассмотреть возможность использования HOF.
def logged[U](f: => U): U = {
log.info("Before")
val ret = f
log.info("After")
ret
}
Здесь у вас есть logged
функция, которая принимает другую функцию f
имеет дело с журналами и делает что угодно f
делает.