title: Update log4j2 pattern at runtime
body: <p>I've searched long and hard, so do read before marking it as duplicate.</p>
  
  <p>I have a function (<code>Lambda.handle()</code>) that's called with a param <code>id</code>. I want to add that id to every log message as prefix. It changes everytime function is called. So I want to update the logger pattern to add this id as prefix.</p>
  
  <p>I've read:</p>
  
  <ul>
  <li><a href="https://logging.apache.org/log4j/2.x/manual/customconfig.html#Configurator" rel="nofollow noreferrer">how to configure</a></li>
  <li><a href="https://logging.apache.org/log4j/2.x/manual/customconfig.html#AddingToCurrent" rel="nofollow noreferrer">how to reconfigure</a></li>
  <li>Numerous posts on SO and log4j forums talking abt how to change config at runtime. They're either outdated or simply don't work.</li>
  </ul>
  
  <p>Following code is based on log4j2 documentation. It prints:</p>
  
  <pre><code>INIT  MyLogger handle() - id ONE 
  INIT  MyLogger handle() - id TWO 
  INIT  MyLogger handle() - id THR 
  </code></pre>
  
  <p>If I comment out line <code>initLoggerConfig("INIT ");</code> then it prints:</p>
  
  <pre><code>ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2
  ONE  MyLogger handle() - id ONE 
  ONE  MyLogger handle() - id TWO 
  ONE  MyLogger handle() - id THR 
  </code></pre>
  
  <p>I want it to print:</p>
  
  <pre><code>ONE  MyLogger handle() - id ONE 
  TWO  MyLogger handle() - id TWO 
  THR  MyLogger handle() - id THR 
  </code></pre>
  
  <p>Whether I comment out <code>ctxLocal = ctx;</code>, has no effect.</p>
  
  <p>Here is <a href="https://pastebin.com/yXjwy4jB" rel="nofollow noreferrer">the full log</a> I get by setting log4j's own logging level to ALL (<code>builder.setStatusLevel(Level.ALL);</code>)</p>
  
  <p>Here is the code</p>
  
  <pre><code>package foobar;
  
  import java.util.Arrays;
  import java.util.List;
  
  import org.apache.logging.log4j.Level;
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  import org.apache.logging.log4j.core.Appender;
  import org.apache.logging.log4j.core.Filter;
  import org.apache.logging.log4j.core.Layout;
  import org.apache.logging.log4j.core.LoggerContext;
  import org.apache.logging.log4j.core.appender.ConsoleAppender;
  import org.apache.logging.log4j.core.config.AppenderRef;
  import org.apache.logging.log4j.core.config.Configuration;
  import org.apache.logging.log4j.core.config.Configurator;
  import org.apache.logging.log4j.core.config.LoggerConfig;
  import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
  import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
  import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
  import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
  import org.apache.logging.log4j.core.layout.PatternLayout;
  
  class Lambda {
    private static final String LOGGER_NAME = "MyLogger";
    private LoggerContext ctx;
  
    public Lambda() {
      initLoggerConfig("INIT ");
    }
  
    public void handle(String id) {
      updateLoggerConfig(id);
      Logger logger = LogManager.getLogger(LOGGER_NAME);
      logger.error("handle() - id {}", id);
    }
  
    private void updateLoggerConfig(String prefix) {
      final LoggerContext ctxLocal = (LoggerContext) LogManager.getContext(false);
      // ctxLocal = ctx;
      Configuration config = ctxLocal.getConfiguration();
      Layout&lt;String&gt; layout = PatternLayout.newBuilder().withPattern(prefix + " %c %m\n").withConfiguration(config)
          .build();
      Appender appender = ConsoleAppender.createDefaultAppenderForLayout(layout);
      appender.start();
      config.addAppender(appender);
      AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
      AppenderRef[] refs = new AppenderRef[] { ref };
      LoggerConfig loggerConfig = LoggerConfig.createLogger(false, Level.ALL, getClass().getName(), "true", refs, null,
          config, null);
      loggerConfig.addAppender(appender, null, null);
      config.addLogger(LOGGER_NAME, loggerConfig);
      ctxLocal.updateLoggers();
    }
  
    void initLoggerConfig(String prefix) {
      ConfigurationBuilder&lt;BuiltConfiguration&gt; builder = ConfigurationBuilderFactory.newConfigurationBuilder();
      builder.setStatusLevel(Level.ERROR);
      builder.setConfigurationName("BuilderTest");
      builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL).addAttribute("level",
          Level.DEBUG));
      AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
          ConsoleAppender.Target.SYSTEM_OUT);
      appenderBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", prefix + " %c %m\n"));
      appenderBuilder.add(
          builder.newFilter("MarkerFilter", Filter.Result.DENY, Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
      builder.add(appenderBuilder);
      builder.add(builder.newLogger(LOGGER_NAME, Level.ALL).add(builder.newAppenderRef("Stdout"))
          .addAttribute("additivity", false));
      builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
      ctx = Configurator.initialize(builder.build());
    }
  }
  
  public class TestMain {
    static Lambda lamb = new Lambda();
    private static Logger logger = LogManager.getLogger();
  
    public static void main(String[] args) {
      Configurator.setLevel(logger.getName(), Level.ALL);
      List&lt;String&gt; a = Arrays.asList("ONE ", "TWO ", "THR ");
      for (String i : a) {
        lamb.handle(i);
      }
  
    }
  }
  </code></pre>