Sunday, August 18, 2013

PerfSpy 2 -- An Aspect to log methods at runtime

PerfSpy uses AspectJ (an AOP library) to inject spying code into application code and stores information into an Oracle database.

The text book definition of aspect-oriented-programing (AOP) is: it is a program paradigm aiming at addressing crosscutting concerns – why software technology has to be read like a legal documentation?

In plain English terms, AOP allows to specify “where” and “what”: where in your code you’d like to do what. “where” is called a “PointCut” (corresponding well to “crosscutting”). The combination of “where” and “what” is called an “Aspect”(do not know why it is named “Aspect”).

For PerfSpy, “where” is the places where the red string passes through – every method invocation, from the entry point to the exit point; “what” is to capture the execution time of every method, and if configured, every input parameter and return value. 

The spying is done by AbstractPerfSpyAspect, it defines where (what kind of methods to capture) and what (capture information).

@Pointcut("!within(com.perfspy.aspect.AbstractPerfSpyAspect+) && !within(com.perfspy..*)")
        public void notMonitoredOps1() {

        @Pointcut("!execution(* toString()) && !within(org.apache.log4j..*)")
        public void notMonitoredOps2() {

        @Pointcut("notMonitoredOps1() && notMonitoredOps2()")
        public void notMonitoredOps() {

        public abstract void cflowOps();

        public abstract void withinCflowOps();

        @Pointcut(" withinCflowOps() && cflowOps() &&  notMonitoredOps()")
        public void monitoredOp() {

        public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
notMonitoredOps1: exclude methods from within PerfSpy

notMonitoredOps2: exclude log4j methods and toString() method

notMonitoredOps: combining notMonitoredOps1 and notMonitoredOps2, to make the code more readable

cflowOps(): resembles the red string that runs through the maze

withinCflowOps(): what kind of methods you’d like to capture

monitoredOp(): combine all the above PointCuts, essentially saying: follow the red string, capture every method it passes through, but leave out certain uninteresting methods

@Around("monitoredOp()"): this is an Around aspect. For every method captured by monitoredOp(), it weaves itself “Around” it, and do spying works:
  • Logging execution time
  • Logging input parameter and return value, if configured
  • Calculate how many times a method is repeatedly invoked

To use PerfSpy, you will need to extend from AbstractPerfSpyAspect, and implement these abstract PointCut:
  • cflowOps()
  • withinCflowOps()
You can also do the following:

  • Plug in your own code analysis. By default, it only analyzes the execution time and repeated invocation times. 
  • Through configuration, define how much information you want to capture: all method inputs/outputs or just some; all classes or just some classes etc.

No comments:

Post a Comment