I would like to add "trace" messages to all my public methods as follows:
public void foo(s:String, n:int) { // log is a log4j logger or any other library log.trace(String.format("Enter foo with s: %s, n: %d", s, n)) ... log.trace("Exit foo") }
Now I would like to add all those log.trace
to my methods automatically with AOP (and byte code instrumentation). I am thinking about AspectJ
. Does it make sense? Do you know any open-source, which does exactly that?
@Loggable
annotation and an AspectJ aspect from jcabi-aspects is a ready mechanism for you (I'm a developer):
@Loggable(Loggable.DEBUG)
public String load(URL url) {
return url.openConnection().getContent();
}
To log both entry and exit, as per the question's requirements:
@Loggable(Loggable.DEBUG, prepend=true)
public String load(URL url) {
return url.openConnection().getContent();
}
All logs go to SLF4J. Check this post for more details.
I have created a simple aspect to capture the execution of public methods. The core of this AspectJ code is the pointcut definition:
pointcut publicMethodExecuted(): execution(public * *(..));
Here we are capturing all public methods with any return type, on any package and any class, with any number of parameters.
The advice execution could be visualized on code snippet below:
after(): publicMethodExecuted() {
System.out.printf("Enters on method: %s. \n", thisJoinPoint.getSignature());
Object[] arguments = thisJoinPoint.getArgs();
for (int i =0; i < arguments.length; i++){
Object argument = arguments[i];
if (argument != null){
System.out.printf("With argument of type %s and value %s. \n", argument.getClass().toString(), argument);
}
}
System.out.printf("Exits method: %s. \n", thisJoinPoint.getSignature());
}
This advice use thisJoinPoint to get the method signature and arguments. And that's it. Here is the aspect code:
public aspect LogAspect {
pointcut publicMethodExecuted(): execution(public * *(..));
after(): publicMethodExecuted() {
System.out.printf("Enters on method: %s. \n", thisJoinPoint.getSignature());
Object[] arguments = thisJoinPoint.getArgs();
for (int i =0; i < arguments.length; i++){
Object argument = arguments[i];
if (argument != null){
System.out.printf("With argument of type %s and value %s. \n", argument.getClass().toString(), argument);
}
}
System.out.printf("Exits method: %s. \n", thisJoinPoint.getSignature());
}
For more complex examples I would recommend the book AspectJ: In Action.
You can use different pointcuts to make your requirement. This documentation will help you.
Straight forward solution
You can try out this open source http://code.google.com/p/perfspy/. PerfSpy is a runtime logging, performance monitoring and code inspecting tool. It uses ApsectJ to weave around your application code at runtime, and logs the execution time of every method and its input parameters and values. It has a UI application, in which you can view the method invocations and their input and return values as trees. With it, you can spot performance bottlenecks and understand complex code flow.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With