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     * &lt;aop:config&gt;
030     *     &lt;aop:aspect id="exceptionLoggingAspect" ref="exceptionLoggingAdvice" order="2"&gt;
031     *         &lt;aop:after-throwing
032     *             pointcut="execution(* org.kuali.student.lum.lu.service.*.*(..))"
033     *             method="afterThrowing" throwing="t" /&gt;
034     *     &lt;/aop:aspect&gt;
035     * &lt;/aop:config&gt;
036     * &lt;bean id="exceptionLoggingAdvice" class="org.kuali.student.common.util.SimpleExceptionLoggingAdvice"&gt;
037     *     &lt;property name="loggingLevel" value="INFO" /&gt;
038     *     &lt;property name="exceptionLoggingType" value="RUNTIME" /&gt;
039     * &lt;/bean&gt;
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    }