001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.impl;
018    
019    import org.apache.camel.CamelContext;
020    import org.apache.camel.CamelExchangeException;
021    import org.apache.camel.Exchange;
022    import org.apache.camel.LoggingLevel;
023    import org.apache.camel.RollbackExchangeException;
024    import org.apache.camel.spi.ExceptionHandler;
025    import org.apache.camel.util.CamelLogger;
026    import org.slf4j.LoggerFactory;
027    
028    /**
029     * A default implementation of {@link ExceptionHandler} which uses a {@link org.apache.camel.util.CamelLogger} to
030     * log the exception.
031     * <p/>
032     * This implementation will by default log the exception with stack trace at WARN level.
033     * <p/>
034     * This implementation honors the {@link org.apache.camel.impl.DefaultShutdownStrategy#isSuppressLoggingOnTimeout()}
035     * option to avoid logging if the logging should be suppressed.
036     *
037     * @version 
038     */
039    public class LoggingExceptionHandler implements ExceptionHandler {
040        private final CamelLogger logger;
041        private final CamelContext camelContext;
042    
043        @Deprecated
044        public LoggingExceptionHandler(Class<?> ownerType) {
045            this(null, new CamelLogger(LoggerFactory.getLogger(ownerType), LoggingLevel.WARN));
046        }
047    
048        public LoggingExceptionHandler(CamelContext camelContext, Class<?> ownerType) {
049            this(camelContext, new CamelLogger(LoggerFactory.getLogger(ownerType), LoggingLevel.WARN));
050        }
051    
052        @Deprecated
053        public LoggingExceptionHandler(Class<?> ownerType, LoggingLevel level) {
054            this(null, new CamelLogger(LoggerFactory.getLogger(ownerType), level));
055        }
056    
057        public LoggingExceptionHandler(CamelContext camelContext, Class<?> ownerType, LoggingLevel level) {
058            this(camelContext, new CamelLogger(LoggerFactory.getLogger(ownerType), level));
059        }
060    
061        @Deprecated
062        public LoggingExceptionHandler(CamelLogger logger) {
063            this(null, logger);
064        }
065    
066        public LoggingExceptionHandler(CamelContext camelContext, CamelLogger logger) {
067            this.camelContext = camelContext;
068            this.logger = logger;
069        }
070    
071        public void handleException(Throwable exception) {
072            handleException(null, null, exception);
073        }
074    
075        public void handleException(String message, Throwable exception) {
076            handleException(message, null, exception);
077        }
078    
079        public void handleException(String message, Exchange exchange, Throwable exception) {
080            try {
081                if (!isSuppressLogging()) {
082                    String msg = CamelExchangeException.createExceptionMessage(message, exchange, exception);
083                    if (isCausedByRollbackExchangeException(exception)) {
084                        // do not log stack trace for intended rollbacks
085                        logger.log(msg);
086                    } else {
087                        if (exception != null) {
088                            logger.log(msg, exception);
089                        } else {
090                            logger.log(msg);
091                        }
092                    }
093                }
094            } catch (Throwable e) {
095                // the logging exception handler must not cause new exceptions to occur
096            }
097        }
098    
099        protected boolean isCausedByRollbackExchangeException(Throwable exception) {
100            if (exception == null) {
101                return false;
102            }
103            if (exception instanceof RollbackExchangeException) {
104                return true;
105            } else if (exception.getCause() != null) {
106                // recursive children
107                return isCausedByRollbackExchangeException(exception.getCause());
108            }
109    
110            return false;
111        }
112    
113        protected boolean isSuppressLogging() {
114            if (camelContext != null) {
115                return (camelContext.getStatus().isStopping() || camelContext.getStatus().isStopped())
116                        && camelContext.getShutdownStrategy().hasTimeoutOccurred() && camelContext.getShutdownStrategy().isSuppressLoggingOnTimeout();
117            } else {
118                return false;
119            }
120        }
121    }