marekzbrzozowa
marekzbrzozowa

Reputation: 392

How could I apply xml config for log4j2 taken from variable instead of file?

How could I apply xml config for log4j2 taken from variable instead of file?

byte[] loggerConfig = getLoggerConfig();
ByteArrayInputStream is = new ByteArrayInputStream(loggerConfig);
ConfigurationSource src = new ConfigurationSource(is);
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
XmlConfiguration cfg = new XmlConfiguration(ctx, src);
//below are some commands which I've tried to use without success
Configuration c = cfg.reconfigure();
cfg.initialize();
cfg.start();
ctx.updateLoggers();

After these operations cfg.appenders and cfg.loggerConfigs contain data from loggerConfig (6 appenders and 7 loggerConfigs) but log4j2 system doesn't work. Xml data are rather OK because log4j2 system works when I read these data from resource file in following way

ctx.setConfigLocation(instance.getClass().getResource(getLoggerConfigFileName()).toURI());

--- sample code ---

I've reduced config to one logger and one appender and in init2 I'm reading xml from file instead of using byte array. I assume that making init2 workable give me solution to the original problem. Current version of init2 writes logs to console instead of configured file (init1 writes correctly to configured file). I'm probably incorectly using ConfigurationSource/XmlConfiguration classes to initialize log4j2 system. Any ideas how to fix it ? I prefer mentioned classes but I could try to use other

log4j.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <RollingRandomAccessFile name="logs" fileName="logs.log"  filePattern="logs.log.%i" immediateFlush="false">
            <PatternLayout pattern="%d %-5p [%c] %m%n" />
            <Policies>
                <SizeBasedTriggeringPolicy size="8 MB" />
            </Policies>
            <DefaultRolloverStrategy max="3" />
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <AsyncLogger name="x" level="ERROR" additivity="false" includeLocation="true">
            <AppenderRef ref="logs" />
        </AsyncLogger>
    </Loggers>
</Configuration>

log4j2v1.java:

package x;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.ConfigurationSource;
import org.apache.logging.log4j.core.config.xml.XmlConfiguration;

import java.io.IOException;
import java.net.URISyntaxException;

public class log4j2v1 {
    private static final log4j2v1 instance = new log4j2v1();
    private static final Logger log = LogManager.getLogger(log4j2v1.class);

    public static void main(String[] args) {
        //init1();  //comment this - uncomment init2
        init2();    //comment this - uncomment init1
        log.error("err1");
        log.info("inf1");
    }

    private static void init1() {
        try {
            LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
            ctx.setConfigLocation(instance.getClass().getResource("../log4j.xml").toURI());
            System.out.println("init1 finished w/o exception");
        } catch (URISyntaxException e) {
        }
    }

    private static void init2() {
        try {
            ConfigurationSource src = new ConfigurationSource(instance.getClass().getResource("../log4j.xml").openStream());
            LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
            XmlConfiguration cfg = new XmlConfiguration(ctx, src);
            //below are some commands which I've tried to use without success
            Configuration c = cfg.reconfigure();
            cfg.initialize();
            cfg.start();
            ctx.updateLoggers();
            System.out.println("init2 finished w/o exception");
        } catch (IOException e) {
        }
    }
}

init1 method initializes log4j2 system, init2 method doesn't initialize log4j2.

Necessary libraries: log4j-api-2.14.1.jar, log4j-core-2.14.1.jar, disruptor-3.4.4.jar

Upvotes: 0

Views: 378

Answers (1)

marekzbrzozowa
marekzbrzozowa

Reputation: 392

It seems command which makes the magic is

Configurator.reconfigure(cfg);

So fixed init2 method should be

    private static void init2() {
        try {
            ConfigurationSource src = new ConfigurationSource(instance.getClass().getResource("l4j2.xml").openStream());
            LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
            XmlConfiguration cfg = new XmlConfiguration(ctx, src);
            Configurator.reconfigure(cfg);
            System.out.println("init2 finished w/o exception");
        } catch (IOException e) {
        }
    }

Upvotes: 0

Related Questions