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 */
017package org.apache.camel.support;
018
019import org.apache.camel.CamelContext;
020import org.apache.camel.CamelExchangeException;
021import org.apache.camel.Exchange;
022import org.apache.camel.LoggingLevel;
023import org.apache.camel.RollbackExchangeException;
024import org.apache.camel.spi.ExceptionHandler;
025import org.apache.camel.util.CamelLogger;
026import 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.spi.ShutdownStrategy#isSuppressLoggingOnTimeout()}
035 * option to avoid logging if the logging should be suppressed.
036 *
037 * @version 
038 */
039public 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}