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.logging.log4j.core.appender;
018
019import java.util.concurrent.TimeUnit;
020
021import org.apache.logging.log4j.Logger;
022import org.apache.logging.log4j.core.Appender;
023import org.apache.logging.log4j.core.ErrorHandler;
024import org.apache.logging.log4j.core.LogEvent;
025import org.apache.logging.log4j.status.StatusLogger;
026
027/**
028 *
029 */
030public class DefaultErrorHandler implements ErrorHandler {
031
032    private static final Logger LOGGER = StatusLogger.getLogger();
033
034    private static final int MAX_EXCEPTIONS = 3;
035
036    private static final long EXCEPTION_INTERVAL = TimeUnit.MINUTES.toNanos(5);
037
038    private int exceptionCount = 0;
039
040    private long lastException = System.nanoTime() - EXCEPTION_INTERVAL - 1;
041
042    private final Appender appender;
043
044    public DefaultErrorHandler(final Appender appender) {
045        this.appender = appender;
046    }
047
048
049    /**
050     * Handle an error with a message.
051     * @param msg The message.
052     */
053    @Override
054    public void error(final String msg) {
055        final long current = System.nanoTime();
056        if (current - lastException > EXCEPTION_INTERVAL || exceptionCount++ < MAX_EXCEPTIONS) {
057            LOGGER.error(msg);
058        }
059        lastException = current;
060    }
061
062    /**
063     * Handle an error with a message and an exception.
064     * @param msg The message.
065     * @param t The Throwable.
066     */
067    @Override
068    public void error(final String msg, final Throwable t) {
069        final long current = System.nanoTime();
070        if (current - lastException > EXCEPTION_INTERVAL || exceptionCount++ < MAX_EXCEPTIONS) {
071            LOGGER.error(msg, t);
072        }
073        lastException = current;
074        if (!appender.ignoreExceptions() && t != null && !(t instanceof AppenderLoggingException)) {
075            throw new AppenderLoggingException(msg, t);
076        }
077    }
078
079    /**
080     * Handle an error with a message, and exception and a logging event.
081     * @param msg The message.
082     * @param event The LogEvent.
083     * @param t The Throwable.
084     */
085    @Override
086    public void error(final String msg, final LogEvent event, final Throwable t) {
087        final long current = System.nanoTime();
088        if (current - lastException > EXCEPTION_INTERVAL || exceptionCount++ < MAX_EXCEPTIONS) {
089            LOGGER.error(msg, t);
090        }
091        lastException = current;
092        if (!appender.ignoreExceptions() && t != null && !(t instanceof AppenderLoggingException)) {
093            throw new AppenderLoggingException(msg, t);
094        }
095    }
096
097    public Appender getAppender() {
098        return appender;
099    }
100}