我有一个用于记录方法调用的spring方法,以及一个有相应的JUnit测试,它有6个测试。对于每个第n次测试,日志打印相关信息n次。因此,当第一个测试运行时,它的信息打印一次(应该是),当第二个测试运行时,它的信息打印两次,依此类推。奇怪的是,这只发生在Eclipse控制台上 - 日志文件本身非常好。 出了什么问题?
这是代码: 记录的春天方面。
public class LogAspect {
/**
* The LOG object to which all the details are sent.
*/
private static final Logger LOG = Logger.getLogger(LogAspect.class);
/**
* Pointcut to identify methods annotated with @LogWithReturnValue.
*/
@Pointcut("@annotation(com.skyfall.aspects.LogWithReturnValue)")
public void logWithReturnValuePointcut() {
}
/**
* Pointcut to identify methods annotated with @Log.
*/
@Pointcut("@annotation(com.skyfall.aspects.Log)")
public void logPointcut() {
}
/**
* Pointcut to identify methods annotated with @LogWithArguments.
*/
@Pointcut("@annotation(com.skyfall.aspects.LogWithArguments)")
public void logWithArgumentsPointcut() {
}
/**
* Pointcut to identify methods annotated with @LogWithArgumentsAndReturnValue.
*/
@Pointcut("@annotation(com.skyfall.aspects.LogWithArgumentsAndReturnValue)")
public void logWithArgumentsAndReturnValuePointcut() {
}
/**
* Pointcut to identify methods annotated with @Metrics.
*
* @param metrics
* Used to access the parameters of the annotation.
*/
@Pointcut("@annotation(metrics)")
public void metricsPointcut(com.skyfall.aspects.Metrics metrics) {
}
/**
* Logs "Entering Method : className.methodName"
*
* @param joinPoint
*/
@Before("logPointcut()")
public void logBefore(JoinPoint joinPoint) {
LOG.info("Entering Method : ".concat(getClassAndName(joinPoint)));
}
/**
* Logs "Entering Method : className.methodName". Also, the list of parameters as : param1 : value1, param2 :
* value2, ...
*
* @param joinPoint
*/
@Before("logWithArgumentsPointcut()")
public void logWithArgumentsBefore(JoinPoint joinPoint) {
LOG.info("Entering Method : ".concat(getClassAndName(joinPoint)));
LOG.info(getParams(joinPoint));
}
/**
* Logs "Exiting Method : className.methodName"
*
* @param joinPoint
*/
@After(" logPointcut() || logWithArgumentsPointcut()")
public void logAfter(JoinPoint joinPoint) {
LOG.info("Exiting Method : ".concat(getClassAndName(joinPoint)).concat("\n"));
}
/**
* Logs calls to methods annotated with @LogWithReturnValue
*
* @param joinPoint
* @return Returns whatever object is returned by the annotated method.
* @throws Throwable
* In case the method throws an exception.
*/
@Around("logWithReturnValuePointcut()")
public Object logWithReturnValue(ProceedingJoinPoint joinPoint) throws Throwable {
LOG.info("Entering Method : ".concat(getClassAndName(joinPoint)));
Object retVal = joinPoint.proceed();
LOG.info("Method returned : ".concat(retVal.toString()));
LOG.info("Exiting Method : ".concat(getClassAndName(joinPoint)).concat("\n"));
return retVal;
}
/**
* Logs calls to methods annotated with @LogWithArgumentsAndReturnValue
*
* @param joinPoint
* @return Returns whatever object is returned by the annotated method.
* @throws Throwable
* In case the method throws an exception.
*/
@Around("logWithArgumentsAndReturnValuePointcut()")
public Object logWithArgumentsAndReturnValue(ProceedingJoinPoint joinPoint) throws Throwable {
LOG.info("Entering Method : ".concat(getClassAndName(joinPoint)));
LOG.info(getParams(joinPoint));
Object retVal = joinPoint.proceed();
LOG.info("Method returned : ".concat(retVal.toString()));
LOG.info("Exiting Method : ".concat(getClassAndName(joinPoint)).concat("\n"));
return retVal;
}
/**
* Logs methods annotated with @Metrics, that exit successfully. Also calculates their running time, and creates a
* UserEvent object to enter into the database. However, that part is not working for now.
*
* @param joinPoint
* @param metrics
* Contains the parameters, if any, passed to the annotation.
* @return Returns whatever object is returned by the annotated method.
* @throws Throwable
* In case the method throws an exception.
*/
@Around("metricsPointcut(metrics)")
public Object metricsTime(ProceedingJoinPoint joinPoint, com.skyfall.aspects.Metrics metrics) throws Throwable {
LOG.info("Entering Method : ".concat(getClassAndName(joinPoint)));
LOG.info(("EventEnum : ").concat(metrics.eventEnum().toString()));
long startTime = System.currentTimeMillis();
Object retVal = joinPoint.proceed();
long endTime = System.currentTimeMillis();
long executionTime = endTime - startTime;
StringBuffer logMessage = new StringBuffer();
logMessage.append("Execution time : ");
logMessage.append(executionTime);
logMessage.append(" ms");
LOG.info(logMessage.toString());
LOG.info("Exiting Method : ".concat(getClassAndName(joinPoint)).concat("\n"));
if (metrics.args() == 0) {
UserEvent userEvent = userEventMaker(joinPoint.getClass().getSimpleName(), joinPoint.getSignature()
.getName(), metrics.eventEnum(), 0, null, executionTime, 1, retVal);
} else {
UserEvent userEvent = userEventMaker(joinPoint.getClass().getSimpleName(), joinPoint.getSignature()
.getName(), metrics.eventEnum(), 1, getParamsList(joinPoint), executionTime, 1, retVal);
}
return retVal;
}
/**
* Logs a method annotated with @Metrics in case it throws an exception.
*
* @param joinPoint
* @param metrics
* Contains the parameters, if any, passed to the annotation.
* @param ex
* The exception that was thrown by the method.
*/
@AfterThrowing(pointcut = "metricsPointcut(metrics)", throwing = "ex")
public void metricsExceptions(JoinPoint joinPoint, com.skyfall.aspects.Metrics metrics, Exception ex) {
if (metrics.args() == 0) {
UserEvent userEvent = userEventMaker(joinPoint.getClass().getSimpleName(), joinPoint.getSignature()
.getName(), metrics.eventEnum(), 0, null, 0, 0, null, ex.toString());
} else {
UserEvent userEvent = userEventMaker(joinPoint.getClass().getSimpleName(), joinPoint.getSignature()
.getName(), metrics.eventEnum(), 1, getParamsList(joinPoint), 0, 0, null, ex.toString());
}
LOG.info(getClassAndName(joinPoint).concat(" has thrown an exception: " + ex.toString()).concat("\n"));
}
JUnit测试:
public class AspectTest extends BasePersistenceTest {
@Before
public void before() {
}
@Test
public void testLog() {
logAspectTester.logF(42);
}
@Test
public void testLogWA() {
logAspectTester.logWAF(42, 7, "string");
}
@Test
public void testLogWRV() {
logAspectTester.logWRVF(42);
}
@Test
public void testLogWAARV() {
logAspectTester.logWAARVF(42, 7, "string");
}
@Test
public void testMetrics() {
logAspectTester.metricsF(42);
}
@Test(expected = Exception.class)
public void testMetricsE() {
logAspectTester.metricsEF(42);
}
}
log4j.properties文件:
# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=logs/skyfall.log
log4j.appender.file.DatePattern='.'yyyy-MM-dd
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p %c{1}:%L - %m%n
# Root logger option
# Change log level to DEBUG instead of INFO if you want debug logs as well
# Append stdout in the end like (INFO, file, stdout) if you want to output logs message on the console as well (but don't commit)
log4j.rootLogger=INFO, file
# Log everything. Good for troubleshooting
log4j.logger.org.hibernate=WARN
log4j.logger.org.apache.struts2 = WARN
# Log all JDBC parameters
#log4j.logger.org.hibernate.type=ALL