Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Logging guards and around advice

We are seeking to use AspectJ to replace a proprietary mechanism for
tracing. The current tracing mechanism uses a code generation approach
(from xml configuration) that enables us to avoid evaluation of
parameters to the trace method. Essentially

 log.trace("a" + b + c.toString() + d.getBuffer())

would not have the string operations executed should the logging level
that currently applies not have tracing on. This is a performance
targeted design feature. We would like to get away from the proprietary
mechanism by using an around advice and a call pointcut (combined with
cflow to prevent recursion etc). However, thus far we can see from
decompiled code that the only thing we have control over is the
invocation of the trace method:

public aspect LoggingGuard {
 /**
     * Avoid recursion into the aspect and
     * into toString calls, which may lead to infinite recursion
     * and StackOverflowError exceptions 
     */
    protected pointcut traceMethods() : (
             !cflow(execution(String *.toString()))
                && !cflow(within(LoggingGuard))
               &&  call(void com.fidelity.Log.trace (..)));
 
 Object around() : traceMethods() {
  Log log = ((Log)(thisJoinPoint.getTarget()));
  if(log.isTraceEnabled()){
   return proceed();
  }
  else
  {
   return null;
  }
 }
} //end LoggingGuard

public class LoggingGuardTest {


    public static void main(String[] args) {

        Log log = new Log();

        //if string is initialized, we should see System.err from the
myMethod() call

        log.trace("Hello "+ myMethod());

    }   


    private static String myMethod(){

        System.err.println("myMethod called!");

        return "myMethod";

    }

}

public static void main(String args[])

{

    Log log = new Log();

    String s = "Hello " + myMethod();

    Log log1 = log;

    JoinPoint joinpoint = Factory.makeJP(ajc$tjp_0, null, log1, s);

    if(!LoggingGuard.ajc$cflowCounter$0.isValid() &&
!LoggingGuard.ajc$cflowCounter$1.isValid())

        trace_aroundBody1$advice(log1, s, joinpoint,
LoggingGuard.aspectOf(), null, joinpoint);

    else

        trace_aroundBody0(log1, s, joinpoint);

}

As you can see the side-effect operations inside the argument list to
the trace method are all executed and only then does the AJ joinpoint
checking kick in.

Is there an advice, pointcut expression or anything else in AspectJ
which would achieve what we need here -- one which would essentially
wrap the whole of the log.trace() rather than just the trace method call
itself.

Thanks,

Ken



Back to the top