1

I tested the solution to a similar question

How can I change the AppenderRef Level in log4j2 programmatically?

But the solution is not working for the latest version of log4j2.xml - 2.17.0 .

Usecase is slight different than the question referred to . I am configuring Log4J programmatically, through a configuration factory :

package test.config;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.config.*;
import org.apache.logging.log4j.core.config.builder.api.*;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import simplica.util.CommonUtils;

import java.io.File;
import java.net.URI;


/**
 * Configuration Factory to configure the Log4J2 Configuration programmatically
 *
 * @version 1.0
 * @author Vishwanath Washimkar
 *
 */

@Plugin(
    name = "CustomConfigurationFactory",
    category = ConfigurationFactory.CATEGORY)
@Order(50)
public class CustomConfigurationFactory extends ConfigurationFactory {


  private LayoutComponentBuilder layoutBuilder;
  private String logDirPath;
  private EmailAppender emailAppender;
  private  String debugLoglevel;
  private AppConfig appConfig;

  private static ConfigurationBuilder<BuiltConfiguration> builder;

  public static LoggerComponentBuilder labwareLogger;


  /**
   * Related to FileAppenders
   */
  private final static String APPN_LAYOUT_PATTERN = "%d{MM-dd@HH:mm:ss}%-4r %-5p [%t] %37c %3x - %m%n";

  public CustomConfigurationFactory(){
    builder = newConfigurationBuilder();
    appConfig = AppConfig.getInstance();

    if(appConfig != null){
      logDirPath = appConfig.getWeblimsLogPath();
      emailAppender = appConfig.getEmailAppender();
    }
  }


  @Override
  protected String[] getSupportedTypes() {
    return new String[] { "*" };
  }

  @Override
  public Configuration getConfiguration(LoggerContext loggerContext, ConfigurationSource source) {
    return null;
  }


  @Override
  public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) {
    return createConfiguration();
  }

  public Configuration createConfiguration() {
    builder.setStatusLevel(Level.WARN);
    builder.setConfigurationName("Test");
    builder.setMonitorInterval("5");
    layoutBuilder = builder.newLayout("PatternLayout").addAttribute("pattern", APPN_LAYOUT_PATTERN);
    RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);

    if (CommonUtils.isValue(logDirPath)) {
      File file = new File(logDirPath);
      if (file.isDirectory() && file.canWrite()) {
        configureWithFileAppender(builder, rootLogger);
      } else {
        configureWithConsoleAppender(builder, rootLogger);
      }
    } else {
      //this is the last re course as every other configuration has failed
      configureWithConsoleAppender(builder,rootLogger);
    }

    if(emailAppender != null){
      if(!emailAppender.getEnabled()){
        //add and enable email appender
        configureEmailAppender(builder,rootLogger);
      }
    }
    builder.add(rootLogger);
    return builder.build();
  }



  private void configureEmailAppender(ConfigurationBuilder<BuiltConfiguration> builder, RootLoggerComponentBuilder rootLogger) {
    String emailAppenderName = "emailAppender";
    AppenderComponentBuilder smtpBuilder = builder.newAppender("emailAppender", "SMTP")//
        .addAttribute("smtpUsername", emailAppender.getSMTPUsername())
        .addAttribute("smtpPassword", emailAppender.getSMTPPassword())
        .addAttribute("smtpProtocol", emailAppender.getSmtpProtocol())
        .addAttribute("smtpHost", emailAppender.getSMTPHost())
        .addAttribute("to", emailAppender.getTo())
        .addAttribute("subject", emailAppender.getSubject())
        .addAttribute("Cc", emailAppender.getCc())
        .addAttribute("Bcc", emailAppender.getBcc())
        .add(layoutBuilder);
    builder.add(smtpBuilder);
    if(emailAppender.getEnabled()){
      rootLogger.add(builder.newAppenderRef(emailAppenderName));
    }

  }

  private void configureWithConsoleAppender(ConfigurationBuilder<BuiltConfiguration> builder, RootLoggerComponentBuilder rootLogger) {
     if(builder == null) throw new IllegalArgumentException("builder cannot be null");
    // create a console appender
    AppenderComponentBuilder appenderBuilder = builder.newAppender("console", "CONSOLE").addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
    appenderBuilder.add(layoutBuilder);
    builder.add(appenderBuilder);
    rootLogger.add(builder.newAppenderRef("console"));
  }

  private void configureWithFileAppender(ConfigurationBuilder<BuiltConfiguration> builder, RootLoggerComponentBuilder rootLogger) {
    if(builder == null) throw new IllegalArgumentException("builder cannot be null");

    ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
        .addComponent(builder.newComponent("TimeBasedTriggeringPolicy").addAttribute("interval", "1"));

    AppenderComponentBuilder debugLogBuilder = builder.newAppender("debugLog", "RollingFile")
        .addAttribute("fileName", logDirPath + "\\" + "debug.log")
        .addAttribute("filePattern", logDirPath + "\\" + "debug%d{MM-dd-yy}.log.gz")
        .add(layoutBuilder)
        .addComponent(triggeringPolicy);

    AppenderComponentBuilder errorLogBuilder = builder.newAppender("errorLog", "RollingFile")
        .addAttribute("fileName", logDirPath + "\\" + "error.log")
        .addAttribute("filePattern", logDirPath + "\\" + "error-%d{MM-dd-yy}.log.gz")
        .add(layoutBuilder)
        .addComponent(triggeringPolicy);

    builder.add(debugLogBuilder);
    builder.add(errorLogBuilder);

    labwareLogger = builder.newLogger("test", Level.DEBUG );
  labwareLogger.add(builder.newAppenderRef("debugLog").addAttribute("level", getDebugLogLevel()));
  labwareLogger.add(builder.newAppenderRef("errorLog").addAttribute("level", Level.ERROR));
    builder.add(labwareLogger);

    rootLogger.add(builder.newAppenderRef("debugLog").addAttribute("level", Level.WARN));
    rootLogger.add(builder.newAppenderRef("errorLog").addAttribute("level", Level.ERROR));
  }

  private Level getDebugLogLevel() {
    String logLevel = appConfig.getDebugLogLevel();
    if("DEBUG".equalsIgnoreCase(logLevel)){
      return Level.DEBUG;
    }

    if("INFO".equalsIgnoreCase(logLevel)){
      return Level.INFO;
    }

    if("ERROR".equalsIgnoreCase(logLevel)){
      return Level.ERROR;
    }

    if("WARN".equalsIgnoreCase(logLevel)){
      return Level.WARN;
    }

    if("FATAL".equalsIgnoreCase(logLevel)){
      return Level.FATAL;
    }

    if("TRACE".equalsIgnoreCase(logLevel)){
      return Level.TRACE;
    }

    if("ALL".equalsIgnoreCase(logLevel)){
      return Level.ALL;
    }

    //at the end lets just return the
    return Level.WARN;
  }

}

Then I am trying to change the logging level for appenderRef in a servlet.

package com.example.testwebapp;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;

import java.io.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
  private String message;

  public void init() {
    message = "Hello World! from Vish";
  }
  
  int i =0;
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    if(i > 2) {
      LoggerContext context = (LoggerContext) LogManager.getContext(false);
      Configuration config = context.getConfiguration();
      LoggerConfig labware = config.getLoggerConfig("labware");
      labware.removeAppender("debugLog");
      labware.addAppender(config.getAppender("debugLog"), Level.DEBUG, null);

// This causes all Loggers to refetch information from their LoggerConfig.
      context.updateLoggers();
    }

    i++;
    response.setContentType("text/html");

    getLog().debug("DEBUG log entryc 11111 ");
    getLog().info("INFO log entry ");
    getLog().error("ERROR log entry ");
    getLog().warn("#############  WAR log entry ");



    // Hello
    PrintWriter out = response.getWriter();
    out.println("<html><body>");
    out.println("<h1>" + message + " World </h1>");
    out.println("</body></html>");
  }

  public void destroy() {
  }

  /**
   * @return The logger for the class.
   */
  private static Log getLog() {
    return LogFactory.getLog(HelloServlet.class);
  }
}

0 Answers0