title: Programmatically create composite filter to define multiple filters in log4j 2
body: <p>To define more than one filter for an element in log4j (version 2) a <strong>composite filter</strong> is required (according to the <a href="https://logging.apache.org/log4j/2.x/manual/filters.html#CompositeFilter" rel="nofollow noreferrer">documentation</a>).
  I can not figure out how to create/add such a filter element when using programmatic configuration:</p>
  <pre><code>
  
      import java.io.IOException;
      import java.net.URI;
      import org.apache.logging.log4j.Level;
      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.Logger;
      import org.apache.logging.log4j.core.Filter;
      import org.apache.logging.log4j.core.LoggerContext;
      import org.apache.logging.log4j.core.appender.ConsoleAppender;
      import org.apache.logging.log4j.core.config.Configuration;
      import org.apache.logging.log4j.core.config.ConfigurationFactory;
      import org.apache.logging.log4j.core.config.ConfigurationSource;
      import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.api.AppenderRefComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.api.CompositeFilterComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
      import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.api.KeyValuePairComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
      import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
  
      public class ConfigurationFactory_Demo {
          
          public static void main(String[] args) {
              ConfigurationFactory configurationFactory = new ConfigurationFactoryClass();
              ConfigurationFactory.setConfigurationFactory(configurationFactory);
              Logger logger = LogManager.getLogger("com.logger");
              logger.info( String.format("Logging Event"));
          }
          
          public static class ConfigurationFactoryClass extends ConfigurationFactory {
              @Override
              public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) {
                  return getConfiguration(loggerContext, source.toString(), null);
              }
              @Override
              public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) {
                  ConfigurationBuilder builder = newConfigurationBuilder();
                  return createConfiguration(name, builder);
              }
              @Override
              protected String[] getSupportedTypes() {
                  return new String[] {"*"};
              }
              
              Configuration createConfiguration(final String configurationName, ConfigurationBuilder configuration) {
                  configuration.setConfigurationName(configurationName);
                  configuration.setStatusLevel(Level.INFO);
                  
                  // Create appender:
                  AppenderComponentBuilder appenderComponent = configuration.newAppender("stdout", "CONSOLE");
                  appenderComponent.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
                  LayoutComponentBuilder layoutComponent = configuration.newLayout("PatternLayout");
                  layoutComponent.addAttribute("pattern", "%msg%n");
                  appenderComponent.add(layoutComponent);                         // adding layout to appender
                  configuration.add(appenderComponent);                            // adding appender to configuration 
                  
                  // Create root logger:
                  RootLoggerComponentBuilder rootLoggerComponent = configuration.newRootLogger(Level.ERROR);
                  rootLoggerComponent.add(configuration.newAppenderRef("stdout"));
                  configuration.add(rootLoggerComponent);                            // adding logger to configuration
  
                  // Create logger:
                  LoggerComponentBuilder loggerComponent = configuration.newLogger("com.logger", Level.TRACE); 
                  loggerComponent.addAttribute("additivity", false);
                  AppenderRefComponentBuilder appenderRefComponent = configuration.newAppenderRef("stdout");
                  appenderRefComponent.addAttribute("level", "TRACE");
                  
                  // Create filter 'Marker':
                  FilterComponentBuilder filterComponent_marker = configuration.newFilter("MarkerFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL);
                  filterComponent_marker.addAttribute("marker", "MarkerTag"); 
                  // Create filter 'Thread Context Map:
                  FilterComponentBuilder filterComponent_threadContextMap;
                  filterComponent_threadContextMap = configuration.newFilter("ThreadContextMapFilter", Filter.Result.ACCEPT, Filter.Result.DENY);
                  KeyValuePairComponentBuilder keyValuePairComponent;
                  keyValuePairComponent = configuration.newKeyValuePair("key", "value");
                  filterComponent_threadContextMap.addComponent(keyValuePairComponent);
  
                  boolean useCompositeFilter = false;
                  if (useCompositeFilter) {
                      CompositeFilterComponentBuilder filterComponent_composite = null;    // HOW TO INITIALIZE 'CompositeFilterComponentBuilder' ? 
                      filterComponent_composite.add(filterComponent_marker);
                      filterComponent_composite.add(filterComponent_threadContextMap);
                      // appenderRefComponent.add(filterComponent_composite);                // HOW TO ADD 'CompositeFilterComponentBuilder' to appender-reference ?
                  } else {
                      appenderRefComponent.add(filterComponent_marker);                    // adding filter directly to appender-reference
                      appenderRefComponent.add(filterComponent_threadContextMap);            // adding second filter directly to appender-reference (NOT ALLOWED)
                  }
                  
                  loggerComponent.add(appenderRefComponent);                                // adding appender-reference to logger 
                  configuration.add(loggerComponent);                                        // adding logger to configuration
                  
                  try { configuration.writeXmlConfiguration(System.out); } catch (IOException e) {}
                  
                  BuiltConfiguration buildConfiguration = configuration.build();
                  return buildConfiguration;
              }
          }
      }
  
  </code></pre>
  <p>This Java code results in the configuration below. It generates the error &quot;AppenderRef has no parameter that matches element ThreadContextMapFilter&quot;.</p>
  <p><code><pre></p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; ?&gt;
  &lt;Configuration name=&quot;18b4aac2&quot; status=&quot;INFO&quot;&gt;
    &lt;Appenders&gt;
      &lt;CONSOLE name=&quot;stdout&quot; target=&quot;SYSTEM_OUT&quot;&gt;
        &lt;PatternLayout pattern=&quot;%msg%n&quot;/&gt;
      &lt;/CONSOLE&gt;
    &lt;/Appenders&gt;
    &lt;Loggers&gt;
      &lt;Root level=&quot;ERROR&quot;&gt;
        &lt;AppenderRef ref=&quot;stdout&quot;/&gt;
      &lt;/Root&gt;
      &lt;Logger name=&quot;com.logger&quot; level=&quot;TRACE&quot; additivity=&quot;false&quot;&gt;
        &lt;AppenderRef ref=&quot;stdout&quot; level=&quot;TRACE&quot;&gt;
          &lt;MarkerFilter onMatch=&quot;ACCEPT&quot; onMismatch=&quot;NEUTRAL&quot; marker=&quot;MarkerTag&quot;/&gt;
          &lt;ThreadContextMapFilter onMatch=&quot;ACCEPT&quot; onMismatch=&quot;DENY&quot;&gt;
            &lt;KeyValuePair key=&quot;key&quot; value=&quot;value&quot;/&gt;
          &lt;/ThreadContextMapFilter&gt;
        &lt;/AppenderRef&gt;
      &lt;/Logger&gt;
    &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  <p></code></pre></p>
  <p>The correct configuration should be:</p>
  <p><code><pre></p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; ?&gt;
  &lt;Configuration name=&quot;18b4aac2&quot; status=&quot;INFO&quot;&gt;
    &lt;Appenders&gt;
      &lt;CONSOLE name=&quot;stdout&quot; target=&quot;SYSTEM_OUT&quot;&gt;
        &lt;PatternLayout pattern=&quot;%msg%n&quot;/&gt;
      &lt;/CONSOLE&gt;
    &lt;/Appenders&gt;
    &lt;Loggers&gt;
      &lt;Root level=&quot;ERROR&quot;&gt;
        &lt;AppenderRef ref=&quot;stdout&quot;/&gt;
      &lt;/Root&gt;
      &lt;Logger name=&quot;com.logger&quot; level=&quot;TRACE&quot; additivity=&quot;false&quot;&gt;
        &lt;AppenderRef ref=&quot;stdout&quot; level=&quot;TRACE&quot;&gt;
          &lt;Filters&gt;
            &lt;MarkerFilter onMatch=&quot;ACCEPT&quot; onMismatch=&quot;NEUTRAL&quot; marker=&quot;MarkerTag&quot;/&gt;
            &lt;ThreadContextMapFilter onMatch=&quot;ACCEPT&quot; onMismatch=&quot;DENY&quot;&gt;
              &lt;KeyValuePair key=&quot;key&quot; value=&quot;value&quot;/&gt;
          &lt;/Filters&gt;
          &lt;/ThreadContextMapFilter&gt;
        &lt;/AppenderRef&gt;
      &lt;/Logger&gt;
    &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  <p></code></pre></p>
  <p>How is it possible to programmatically define a composite filter in this case?</p>