简体   繁体   中英

How to separate a Log4j configuration?

I've got a program that has a log4j configuration written in XML. I am trying to modify the original application, and attempting to improve upon the previous logger config.

Since I cannot modify the xml file itself, I want to be able to generate a new configuration through the ConfigurationBuilderFactory , and use it alongside the other config. The only issue is that, I am unable to accomplish this. It does not seem to want to work with both.

What can I do?

The following is my code, greatly simplified:

/**
 * Internally uses {@link org.apache.logging.log4j.Logger}
 */
public final class MyLogger {
    private static final LoggerContext context;

    static {
        ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
        {
            builder.setStatusLevel(WARN);

            AppenderComponentBuilder console = builder.newAppender("SysOut", "Console");
            console.addAttribute(...);
            console.add(builder.newLayout(...).addAttribute(...));
            builder.add(console);

            // ... more configuration below
        }

        context = Configurator.initialize(builder.build()); // only works if no previous config exists, but will not replace an old config
    }
}

// later on...

context.getLogger("MyLogger"); // uses the xml config, not the one written above

I think you can create your own log4j.xml . You have to ensure that your XML will be loaded in your program. So just define the resource containing your XML in the Java Classpath before the resource containing the other XML.

For creating loggers using the ConfigurationBuilder API programmatically you can refer below code.

It creates a logger in log4j2 environment added with some layout and appenders defined :

public class Log4j2Logger {

int counter = 0;

LoggerContext ctx;

Configuration config;

Logger logger;

String loggerName = "testLogger";

String appenderName = "myAppender";

static String testMessage = "This is a Test Message";

public void log() {

    final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
    final LoggerComponentBuilder loggerComp = builder.newLogger(loggerName, Level.ALL).addAttribute("additivity",
            false);
    builder.add(loggerComp);
    config = builder.build();
    ctx = Configurator.initialize(config);
    config = ctx.getConfiguration();
    ctx.start(config);
    ctx.updateLoggers(config);

    // To create/add the logger of the configuration specified above we can use the
    // getLogger(..) method
    logger = ctx.getLogger(loggerName);

    // Now we need to attach an appender to the logger so that our messages could be
    // logged
    logger.addAppender(addConsoleAppender(ctx.getConfiguration(), appenderName));
    while (counter < 10) {
        logger.error(testMessage + counter);
        counter++;
    }

}

private Appender addConsoleAppender(Configuration config, String appenderName) {
    Appender consoleAppender = ConsoleAppender.newBuilder().setConfiguration(config).setName(appenderName)
            .withImmediateFlush(true).build();
    consoleAppender.start();
    return consoleAppender;
    }

}

And for testing, you can have following in any test class:

Log4j2Logger testLogger = new Log4j2Logger();
testLogger.log();

This API helps you to handle logs in a powerful way.

You can :

  • Create multiple loggers with your configuration
  • Add multiple Appenders to it.
  • Configure them also.
  • Remove logger when the usage is over.
  • Create Asynchronous Loggers also.

PS : I have used log4j2 version 2.12.1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM