I am trying to define an aspect to inject a logger.
I am looking to create something like:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public aspect LogInjector {
private pointcut executionJoinPoints(): !within(LogInjector) && execution (* *.*(..));
before(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get params name, type and values triplet or values at least if the previous is not possible, of the executed code
params = ...
// Get call stack of the executed code
stack = ...
logger.trace("{}.{}({}) - {}", clazz.name(), method.name(), params, stack);
}
after(): executionJoinPoints(){
// Get class name of the executed code
clazz = ...
final Logger logger = LogManager.getLogger(clazz);
// Get method name of the executed code
method = ...
// Get return value or exception of the executed code
result = ...
logger.trace("{}.{} = {}", clazz.name(), method.name(), result);
}
}
For this I want to retrieve execution metadata/context data:
How can get this metadata/context data?
In order to keep your aspect efficient, I recommend the following:
around()
advice instead of a before()
/ after()
pair. Then you only need to calculate some of the logged values once and use them both before and after the original method call done via proceed()
.thisJoinPoint
instead of piecing together bits contained therein by default. This will already give you the type of joinpoint, method signature including parameter types and return value.around()
advice mentioned above you can enclose the proceed()
call into try-catch-finally
and conveniently handle and log any exceptions and stack traces and/or wrap checked exceptions into AspectJ's SoftException
or a simple RuntimeException
and re-throw them. Whatever is applicable to your situation.proceed()
, which would you also be what you need to return from the around()
advice. You can also return something else instead (but it must have the correct return type) or completely skip proceed()
if for whatever reason you wish to skip target method execution.All of what I just said is written in the AspectJ manual or in any other AspectJ tutorial. You might want to read some of those next time before asking a general question like this one.