001 /**
002 * Copyright 2010 The Kuali Foundation Licensed under the
003 * Educational Community License, Version 2.0 (the "License"); you may
004 * not use this file except in compliance with the License. You may
005 * obtain a copy of the License at
006 *
007 * http://www.osedu.org/licenses/ECL-2.0
008 *
009 * Unless required by applicable law or agreed to in writing,
010 * software distributed under the License is distributed on an "AS IS"
011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
012 * or implied. See the License for the specific language governing
013 * permissions and limitations under the License.
014 */
015
016 package org.kuali.student.common.util;
017
018 import org.aspectj.lang.JoinPoint;
019 import org.slf4j.Logger;
020 import org.slf4j.LoggerFactory;
021 import org.springframework.aop.ThrowsAdvice;
022
023 /**
024 * Advice to log exceptions.
025 * Default <code>loggingLevel=STACKTRACE</code> and <code>exceptionLoggingType=THROWABLE</code>.
026 *
027 * <p>Spring configuration example</p>
028 * <pre>
029 * <aop:config>
030 * <aop:aspect id="exceptionLoggingAspect" ref="exceptionLoggingAdvice" order="2">
031 * <aop:after-throwing
032 * pointcut="execution(* org.kuali.student.lum.lu.service.*.*(..))"
033 * method="afterThrowing" throwing="t" />
034 * </aop:aspect>
035 * </aop:config>
036 * <bean id="exceptionLoggingAdvice" class="org.kuali.student.common.util.SimpleExceptionLoggingAdvice">
037 * <property name="loggingLevel" value="INFO" />
038 * <property name="exceptionLoggingType" value="RUNTIME" />
039 * </bean>
040 * </pre>
041 */
042 public class SimpleExceptionLoggingAdvice implements ThrowsAdvice {
043
044 private enum ExceptionLevel{THROWABLE, EXCEPTION, RUNTIME};
045 private ExceptionLevel exceptionType = ExceptionLevel.THROWABLE;
046
047 private enum LoggingLevel{NONE, DEBUG, INFO, WARN, ERROR, STACKTRACE};
048 private LoggingLevel loggingLevel = LoggingLevel.STACKTRACE;
049
050 /**
051 * Constructor.
052 */
053 public SimpleExceptionLoggingAdvice() {
054 }
055
056 /**
057 * Sets the logging level.
058 * <p>Logging levels:</p>
059 * <ul>
060 * <li>NONE</li>
061 * <li>DEBUG</li>
062 * <li>INFO</li>
063 * <li>WARN</li>
064 * <li>ERROR</li>
065 * <li>STACKTRACE</li>
066 * </ul>
067 * @param loggingLevel Logging level
068 */
069 public void setLoggingLevel(String loggingLevel) {
070 this.loggingLevel = LoggingLevel.valueOf(loggingLevel.toUpperCase());
071 }
072
073 /**
074 * Sets the type of exception to log.
075 * E.g. Only log runtime exception (<code>RUNTIME</code>).
076 *
077 * <p>Exception types:</p>
078 * <ul>
079 * <li>THROWABLE</li>
080 * <li>EXCEPTION</li>
081 * <li>RUNTIME</li>
082 * </ul>
083 *
084 * @param exceptionType exception logging type
085 */
086 public void setExceptionLoggingType(String exceptionType) {
087 this.exceptionType = ExceptionLevel.valueOf(exceptionType.toUpperCase());
088 }
089
090 /**
091 * Catches the exception being thrown.
092 *
093 * @param jp Aspect join point
094 * @param t Exception being thrown
095 * @throws Throwable
096 */
097 public void afterThrowing(JoinPoint jp, Throwable t) throws Throwable {
098 switch(this.exceptionType) {
099 case THROWABLE:
100 if(t instanceof Throwable) {
101 logException(jp.getTarget().getClass(), t);
102 }
103 case EXCEPTION:
104 if(t instanceof Exception) {
105 logException(jp.getTarget().getClass(), t);
106 }
107 case RUNTIME:
108 if(t instanceof RuntimeException) {
109 logException(jp.getTarget().getClass(), t);
110 }
111 }
112 throw t;
113 }
114
115 /**
116 * Logs the exception.
117 *
118 * @param targetClass The join point class the exception was caught.
119 * @param t Exception being thrown.
120 */
121 private void logException(Class<?> targetClass, Throwable t) {
122 Logger logger = LoggerFactory.getLogger(targetClass);
123
124 switch(this.loggingLevel) {
125 case NONE:
126 break;
127 case DEBUG:
128 logger.debug(t.getMessage(), t);
129 break;
130 case INFO:
131 logger.info(t.getMessage(), t);
132 break;
133 case WARN:
134 logger.warn(t.getMessage(), t);
135 break;
136 case ERROR:
137 logger.error(t.getMessage(), t);
138 break;
139 case STACKTRACE:
140 logger.error(t.getMessage(), t);
141 break;
142 }
143 }
144 }