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);
}
}