Using AspectJ to log all methods parameters and return values during application runtime
AspectJ is an aspect-oriented extension created at PARC for the Java programming language. It is available in Eclipse Foundation open-source projects, both stand-alone and integrated into Eclipse. AspectJ has become the widely used de-facto standard for AOP by emphasizing simplicity and usability for end users. It uses Java-like syntax and has included IDE integrations for displaying crosscutting structure since its initial public release in 2001. To use AspectJ to log all application methods and methods return values, follow the below guide...
Use the following aspect utility class:
-
package com.myapp.util;
-
-
import java.lang.reflect.Field;
-
import java.util.List;
-
-
import org.apache.log4j.Logger;
-
-
public final class AspectUtils {
-
-
private static final Logger logger = Logger.getLogger(AspectUtils.class);
-
-
private AspectUtils() {
-
-
}
-
-
public static Logger getLogger(org.aspectj.lang.JoinPoint joinPoint) {
-
try {
-
@SuppressWarnings("rawtypes")
-
Class declaringType = joinPoint.getSignature().getDeclaringType();
-
loggerField.setAccessible(true);
-
return (Logger) loggerField.get(null);
-
-
-
}
-
return logger;
-
}
-
-
public static void logParamValues(StringBuilder logLine,
-
for (int i = 0; i < paramValues.length; i++) {
-
logLine.append(paramNames[i]).append("=")
-
.append(toString(paramValues[i]));
-
if (i < paramValues.length - 1)
-
logLine.append(", ");
-
}
-
}
-
-
@SuppressWarnings("rawtypes")
-
if (object == null)
-
return "<null>";
-
}
-
else
-
return "object";
-
}
-
}
the class contains 3 methods, "getLogger" will extract the logger attribute of the method class not to change the logger class name
the 2nd method "logParamValues" format the log of the method in form "methodName(param1=xxxx, param2=xxxx)"
the 3rd method "toString", converts an object to a string format but not the same as the built in toString object method
Use the following enum to prevent logging on specific method, just annotate the method with @NO_LOG and aspectJ will ignore the method :
-
package com.myapp.util;
-
-
public @interface NO_LOG {
-
-
}
now for the aspect file [don't forget to configure aspectJ in your class path]:
-
import java.util.List;
-
-
import org.aspectj.lang.reflect.CodeSignature;
-
-
import com.myapp.util.AspectUtils;;
-
-
public aspect ServicesLogger {
-
-
pointcut logMethod():
-
execution(!@com.myapp.util.NO_LOG * com.myapp.services..* (..));
-
-
before(): logMethod() {
-
.getSignature()).getParameterNames();
-
StringBuilder logLine = new StringBuilder(thisJoinPointStaticPart
-
.getSignature().getName()).append("(");
-
if (paramNames.length != 0)
-
AspectUtils.logParamValues(logLine, paramNames, paramValues);
-
logLine.append(") - started");
-
AspectUtils.getLogger(thisJoinPoint).info(logLine.toString());
-
}
-
-
@SuppressWarnings("rawtypes")
-
-
StringBuilder rv = new StringBuilder("Return Value : ");
-
rv.append(AspectUtils.toString(r));
-
AspectUtils.getLogger(thisJoinPoint).info(rv.toString());
-
}
-
-
.getSignature()).getParameterNames();
-
StringBuilder logLine = new StringBuilder(thisJoinPointStaticPart
-
.getSignature().getName()).append("(");
-
if (paramNames.length != 0)
-
AspectUtils.logParamValues(logLine, paramNames, paramValues);
-
logLine.append(") - finished");
-
AspectUtils.getLogger(thisJoinPoint).info(logLine.toString());
-
}
-
}
- 3470 reads
Add new comment