/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.core.config;

import org.apache.logging.log4j.core.ErrorHandler;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AppenderRuntimeException;
import org.apache.logging.log4j.core.appender.DefaultErrorHandler;

/**
 *
 */
public class AppenderControl {

    private final Appender appender;

    AppenderControl(Appender appender) {
        this.appender = appender;
    }

    public Appender getAppender() {
        return appender;
    }

    public void callAppender(LogEvent event) {
        if (!appender.isStarted()) {
            appender.getHandler().error("Attempted to append to non-started appender " + appender.getName());

            if (!appender.suppressException()) {
                throw new AppenderRuntimeException("Attempted to append to non-started appender " + appender.getName());
            }
        }

        Filter.Result result = Filter.Result.NEUTRAL;

        for (Filter filter : appender.getFilters()) {
            result = filter.filter(event);
            if (result != Filter.Result.NEUTRAL) {
                break;
            }
        }
        if (result == Filter.Result.DENY) {
            return;
        }

        try {
            appender.append(event);
        } catch (Exception ex) {
            appender.getHandler().error("An exception occurred processing Appender " + appender.getName(), ex);
            if (!appender.suppressException()) {
                throw new AppenderRuntimeException(ex);
            }
        }
    }

}

@@ -1181,43 +1181,220 @@
 *%0A *
-%0A */%0Apublic class AppenderControl %7B
+ Wraps appenders with details the appender implementation shouldn't need to know about.%0A */%0Apublic class AppenderControl %7B%0A%0A    private ThreadLocal%3CAppenderControl%3E recursive = new ThreadLocal%3CAppenderControl%3E();
 %0A%0A  
@@ -1622,24 +1622,238 @@
 nt event) %7B%0A
+        if (recursive.get() != null) %7B%0A            appender.getHandler().error(%22Recursive call to appender %22 + appender.getName());%0A            return;%0A        %7D%0A        try %7B%0A            recursive.set(this);%0A%0A    
         if (
@@ -1873,24 +1873,28 @@
 tarted()) %7B%0A
+    
             
@@ -1996,32 +1996,36 @@
 );%0A%0A            
+  
+  
 if (!appender.su
@@ -2037,32 +2037,36 @@
 sException()) %7B%0A
+    
                 
@@ -2174,32 +2174,36 @@
 ));%0A            
+    
 %7D%0A        %7D%0A%0A   
@@ -2188,35 +2188,43 @@
       %7D%0A        
+ 
-%7D%0A%0A
+   %7D%0A%0A    
         Filter.R
@@ -2270,16 +2270,20 @@
         
+    
 for (Fil
@@ -2332,16 +2332,20 @@
         
+ 
+   
 result =
@@ -2359,32 +2359,36 @@
 .filter(event);%0A
+    
             if (
@@ -2418,24 +2418,28 @@
 .NEUTRAL) %7B%0A
+    
             
@@ -2457,36 +2457,48 @@
             
-%7D%0A    
     %7D%0A
+            %7D%0A    
         if (
@@ -2533,32 +2533,36 @@
 ) %7B%0A            
+    
 return;%0A        
@@ -2561,27 +2561,34 @@
         
-%7D%0A%0A
+    %7D%0A%0A   
         
 try %7B%0A  
@@ -2571,38 +2571,43 @@
   %7D%0A%0A           
+ 
 try %7B%0A
+    
             appe
@@ -2634,16 +2634,20 @@
         
+    
 %7D catch 
@@ -2667,32 +2667,36 @@
 ) %7B%0A            
+   
+ 
 appender.getHand
@@ -2783,32 +2783,36 @@
 x);%0A            
+    
 if (!appender.su
@@ -2824,32 +2824,36 @@
 sException()) %7B%0A
+    
                 
@@ -2896,33 +2896,104 @@
 x);%0A            
+  
-%7D
+  %7D%0A            %7D%0A        %7D finally %7B%0A            recursive.set(null);
 %0A        %7D%0A    %7D

Prevent recursive appender calls