diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractMonitoringInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractMonitoringInterceptor.java index 1bd6a6d5e1..a742be2cb6 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractMonitoringInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractMonitoringInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,12 +22,12 @@ import org.aopalliance.intercept.MethodInvocation; /** * Base class for monitoring interceptors, such as performance monitors. - * Provides {@code prefix} and {@code suffix} properties - * that help to classify/group performance monitoring results. + * Provides configurable "prefix and "suffix" properties that help to + * classify/group performance monitoring results. * - *

Subclasses should call the {@code createInvocationTraceName(MethodInvocation)} - * method to create a name for the given trace that includes information about the - * method invocation under trace along with the prefix and suffix added as appropriate. + *

In their {@link #invokeUnderTrace} implementation, subclasses should call the + * {@link #createInvocationTraceName} method to create a name for the given trace, + * including information about the method invocation along with a prefix/suffix. * * @author Rob Harrop * @author Juergen Hoeller diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractTraceInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractTraceInterceptor.java index 00ae0a2d81..7450df1438 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractTraceInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/AbstractTraceInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,6 +58,12 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser */ private boolean hideProxyClassNames = false; + /** + * Indicates whether to pass an exception to the logger. + * @see #writeToLog(Log, String, Throwable) + */ + private boolean logExceptionStackTrace = true; + /** * Set whether to use a dynamic logger or a static logger. @@ -98,6 +104,17 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser this.hideProxyClassNames = hideProxyClassNames; } + /** + * Set whether to pass an exception to the logger, suggesting inclusion + * of its stack trace into the log. Default is "true"; set this to "false" + * in order to reduce the log output to just the trace message (which may + * include the exception class name and exception message, if applicable). + * @since 4.3.10 + */ + public void setLogExceptionStackTrace(boolean logExceptionStackTrace) { + this.logExceptionStackTrace = logExceptionStackTrace; + } + /** * Determines whether or not logging is enabled for the particular {@code MethodInvocation}. @@ -171,6 +188,40 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser return logger.isTraceEnabled(); } + /** + * Write the supplied trace message to the supplied {@code Log} instance. + *

To be called by {@link #invokeUnderTrace} for enter/exit messages. + *

Delegates to {@link #writeToLog(Log, String, Throwable)} as the + * ultimate delegate that controls the underlying logger invocation. + * @since 4.3.10 + * @see #writeToLog(Log, String, Throwable) + */ + protected void writeToLog(Log logger, String message) { + writeToLog(logger, message, null); + } + + /** + * Write the supplied trace message and {@link Throwable} to the + * supplied {@code Log} instance. + *

To be called by {@link #invokeUnderTrace} for enter/exit outcomes, + * potentially including an exception. Note that an exception's stack trace + * won't get logged when {@link #setLogExceptionStackTrace} is "false". + *

By default messages are written at {@code TRACE} level. Subclasses + * can override this method to control which level the message is written + * at, typically also overriding {@link #isLogEnabled} accordingly. + * @since 4.3.10 + * @see #setLogExceptionStackTrace + * @see #isLogEnabled + */ + protected void writeToLog(Log logger, String message, Throwable ex) { + if (ex != null && this.logExceptionStackTrace) { + logger.trace(message, ex); + } + else { + logger.trace(message); + } + } + /** * Subclasses must override this method to perform any tracing around the @@ -180,13 +231,15 @@ public abstract class AbstractTraceInterceptor implements MethodInterceptor, Ser *

By default, the passed-in {@code Log} instance will have log level * "trace" enabled. Subclasses do not have to check for this again, unless * they overwrite the {@code isInterceptorEnabled} method to modify - * the default behavior. + * the default behavior, and may delegate to {@code writeToLog} for actual + * messages to be written. * @param logger the {@code Log} to write trace messages to * @return the result of the call to {@code MethodInvocation.proceed()} * @throws Throwable if the call to {@code MethodInvocation.proceed()} * encountered any errors - * @see #isInterceptorEnabled * @see #isLogEnabled + * @see #writeToLog(Log, String) + * @see #writeToLog(Log, String, Throwable) */ protected abstract Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable; diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/CustomizableTraceInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/CustomizableTraceInterceptor.java index 2e0aa2ef7d..7598f7ad91 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/CustomizableTraceInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/CustomizableTraceInterceptor.java @@ -275,29 +275,6 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor { } } - /** - * Writes the supplied message to the supplied {@code Log} instance. - * @see #writeToLog(org.apache.commons.logging.Log, String, Throwable) - */ - protected void writeToLog(Log logger, String message) { - writeToLog(logger, message, null); - } - - /** - * Writes the supplied message and {@link Throwable} to the - * supplied {@code Log} instance. By default messages are written - * at {@code TRACE} level. Sub-classes can override this method - * to control which level the message is written at. - */ - protected void writeToLog(Log logger, String message, Throwable ex) { - if (ex != null) { - logger.trace(message, ex); - } - else { - logger.trace(message); - } - } - /** * Replace the placeholders in the given message with the supplied values, * or values derived from those supplied. diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/JamonPerformanceMonitorInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/JamonPerformanceMonitorInterceptor.java index a1955bc291..2b71b3cbbd 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/JamonPerformanceMonitorInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/JamonPerformanceMonitorInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -121,7 +121,7 @@ public class JamonPerformanceMonitorInterceptor extends AbstractMonitoringInterc finally { monitor.stop(); if (!this.trackAllInvocations || isLogEnabled(logger)) { - logger.trace("JAMon performance statistics for method [" + name + "]:\n" + monitor); + writeToLog(logger, "JAMon performance statistics for method [" + name + "]:\n" + monitor); } } } diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/PerformanceMonitorInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/PerformanceMonitorInterceptor.java index 4362c5de10..dd72c00f35 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/PerformanceMonitorInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/PerformanceMonitorInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ public class PerformanceMonitorInterceptor extends AbstractMonitoringInterceptor } finally { stopWatch.stop(); - logger.trace(stopWatch.shortSummary()); + writeToLog(logger, stopWatch.shortSummary()); } } diff --git a/spring-aop/src/main/java/org/springframework/aop/interceptor/SimpleTraceInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/interceptor/SimpleTraceInterceptor.java index e70f502fd1..8ca8baa8ae 100644 --- a/spring-aop/src/main/java/org/springframework/aop/interceptor/SimpleTraceInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/interceptor/SimpleTraceInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,14 +55,14 @@ public class SimpleTraceInterceptor extends AbstractTraceInterceptor { @Override protected Object invokeUnderTrace(MethodInvocation invocation, Log logger) throws Throwable { String invocationDescription = getInvocationDescription(invocation); - logger.trace("Entering " + invocationDescription); + writeToLog(logger, "Entering " + invocationDescription); try { Object rval = invocation.proceed(); - logger.trace("Exiting " + invocationDescription); + writeToLog(logger, "Exiting " + invocationDescription); return rval; } catch (Throwable ex) { - logger.trace("Exception thrown in " + invocationDescription, ex); + writeToLog(logger, "Exception thrown in " + invocationDescription, ex); throw ex; } }