title: How to Set Log4j Properties Programmatically with Lombok
body: <p>Log4j allows me to easily setup logging with each class. I want to change properties of my JavaFX application on initialization. What I want to do is to create log files under user's <code>%appdata%/&lt;app&gt;/&lt;version&gt;</code> directory (for the sake of example). I found a <a href="https://logging.apache.org/log4j/2.x/manual/customconfig.html" rel="nofollow noreferrer">documentation</a> about programmatically set the properties of logger.</p>
  
  <p>I have a very similar Log4j <code>ConfigurationFactory</code> as follows.</p>
  
  <pre><code>public class Log4jConfigurationFactory extends ConfigurationFactory {
      @Override
      protected String[] getSupportedTypes() {
          return new String[] {"*"};
      }
  
      private static Configuration createConfiguration(final String name, ConfigurationBuilder&lt;BuiltConfiguration&gt; builder) {
          builder.setConfigurationName(name);
          builder.setStatusLevel(Level.DEBUG);
  
          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", "%d [%t] %-5level: %msg%n%throwable"));
          appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY,
                  Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
  
          builder.add(appenderBuilder);
          builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
                  add(builder.newAppenderRef("Stdout")).
                  addAttribute("additivity", false));
          builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
          return builder.build();
      }
  
      @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&lt;BuiltConfiguration&gt; builder = newConfigurationBuilder();
          return createConfiguration(name, builder);
      }
  }
  </code></pre>
  
  <p>And I have a main class as below:</p>
  
  <pre><code>@Log4j2
  public class App extends GenericApplication { // this GenericApplication extends Application, it is from a library I use, no worries.
      @Override
      public void init() throws Exception {
          super.init();
          log.debug("Hey."); // for testing purposes
      }
  
      @Override
      public void start(Stage primaryStage) {
          super.start(primaryStage);
      }
  
      @Override
      public void stop() throws Exception {
          log.error("Hey."); // for testing purposes
      }
  
      public static void main(String[] args ) {
          GenericApplication.launch(args);
      }
  }
  </code></pre>
  
  <p>The problem is that Log4j <em>naturally</em> does not find my custom <code>Log4jConfigurationFactory</code>. It seems Lombok does not have <code>Log4j</code> annotation to provide a custom <code>ConfigurationFactory</code> (according to its <a href="https://projectlombok.org/features/log" rel="nofollow noreferrer">documentation</a>, the only argument <code>Log</code> annotation might have is <code>topic</code> purpose of which is to give a human-readable (?) <code>Logger</code> title.).</p>
  
  <p>So, how do I use custom <code>ConfigurationFactory</code> with Lombok?</p>
  
  <p>Thanks in advance.</p>
  
  <hr>
  
  <h1>Environment</h1>
  
  <pre><code>Group ID: org.projectlombok
  Artifact ID: lombok
  Version: 1.16.20
  
  Group ID: org.apache.logging.log4j
  Artifact ID: log4j-core
  Version: 2.11.0
  </code></pre>