Configuration 来自XML字节流的Log4J2编程配置

Configuration 来自XML字节流的Log4J2编程配置,configuration,initialization,log4j2,Configuration,Initialization,Log4j2,我对Log4J2已经束手无策了,希望有人能帮助我。启动后不久,我有以下代码来初始化Log4J2: try (InputStream configStream = new ByteArrayInputStream(writer.toString().getBytes("UTF-8"))) { ConfigurationSource configurationSource = new ConfigurationSource(configStream); Con

我对Log4J2已经束手无策了,希望有人能帮助我。启动后不久,我有以下代码来初始化Log4J2:

try (InputStream configStream = new ByteArrayInputStream(writer.toString().getBytes("UTF-8"))) {            
    ConfigurationSource configurationSource = new ConfigurationSource(configStream);
    Configurator.initialize(null, configurationSource);
}
其中writer是一个StringWriter,toString()生成以下配置(我已经通过其他方式验证了它是正确的):

我之所以说这是意料之中的,是因为我正在手动配置Log4J2,但尚未抑制此消息

不幸的是,由于遗留的原因,我无法从文件中读取配置

更新1:

在接受Remko的建议后,我在调用initialize方法之前添加了以下块:

System.setProperty("log4j2.disable.jmx", "true");
StatusLogger status = StatusLogger.getLogger();
status.clear(); // remove old listeners that may prevent status output
status.setLevel(Level.TRACE);
status.reset(); // I could not see any trace info until I called this
status.trace("Status -- TRACE"); // I added this to prove that trace level logging was working
这给了我以下输出:

ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.
TRACE StatusLogger Status -- TRACE
DEBUG StatusLogger Stopping LoggerContext[name=sun.misc.Launcher$AppClassLoader@647e05, org.apache.logging.log4j.core.LoggerContext@a3defe]
DEBUG StatusLogger Stopping LoggerContext[name=sun.misc.Launcher$AppClassLoader@647e05, org.apache.logging.log4j.core.LoggerContext@a3defe]...
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@647e05
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@647e05,component=StatusLogger
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@647e05,component=ContextSelector
DEBUG StatusLogger Unregistering MBean org.apache.logging.log4j2:type=sun.misc.Launcher$AppClassLoader@647e05,component=Appenders,name=Console
TRACE StatusLogger Stopping org.apache.logging.log4j.core.config.DefaultConfiguration@1a1440e...
TRACE StatusLogger AbstractConfiguration stopped 0 AsyncLoggerConfigs.
TRACE StatusLogger AbstractConfiguration stopped 0 AsyncAppenders.
DEBUG StatusLogger Shutting down OutputStreamManager SYSTEM_OUT
TRACE StatusLogger AbstractConfiguration stopped 1 Appenders.
TRACE StatusLogger AbstractConfiguration stopped 0 Loggers.
DEBUG StatusLogger Stopped org.apache.logging.log4j.core.config.DefaultConfiguration@9a6398 OK
DEBUG StatusLogger Stopped LoggerContext[name=sun.misc.Launcher$AppClassLoader@647e05, org.apache.logging.log4j.core.LoggerContext@9a6398]...
更新2:

我决定找到一种使用文件而不是ByteArrayInputStream的方法,并让它工作起来。FWIW,我认为Log4J2代码中有一个bug,当尝试使用InputStream初始化时,我的理论是:

在Log4jContextFactory中,使用以下方法:

public LoggerContext getContext(final String fqcn, final ClassLoader loader, final Object externalContext,
                                final boolean currentContext, final ConfigurationSource source)
具有以下if语句,该语句的计算结果始终为false,这意味着始终返回默认配置

if (ctx.getState() == LifeCycle.State.INITIALIZED) {
    if (source != null) {
        ContextAnchor.THREAD_CONTEXT.set(ctx);
        final Configuration config = ConfigurationFactory.getInstance().getConfiguration(source);
        LOGGER.debug("Starting LoggerContext[name={}] from configuration {}", ctx.getName(), source);
        ctx.start(config);
        ContextAnchor.THREAD_CONTEXT.remove();
    } else {
        ctx.start();
    }
}

乍一看,我不明白为什么您的配置不起作用。(您可以尝试在路径中使用正向斜杠以确保绝对正确,但斜杠可能不是问题所在。)

您是否可以尝试以下方法来生成更多log4j2调试输出,以查看配置哪里出错?请在你的问题中公布结果

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.status.StatusLogger;

// In an XML configuration you can just use <Configuration status="TRACE"...
// Here we use less elegant code to switch on status logging 
// since we're not sure where things break down.
System.setProperty("log4j2.disable.jmx", "true");
StatusLogger status = StatusLogger.getLogger();
status.clear(); // remove old listeners that may prevent status output
status.setLevel(Level.TRACE);

// now configure log4j2...
// This should generate trace-level debug output to the console.
try (InputStream configStream = new ByteArrayInputStream(writer.toString().getBytes())) {            
    ConfigurationSource configurationSource = new ConfigurationSource(configStream);
    Configurator.initialize(null, configurationSource);
}
import org.apache.logging.log4j.Level;
导入org.apache.logging.log4j.status.StatusLogger;
//在XML配置中,您只需使用
if (ctx.getState() == LifeCycle.State.INITIALIZED) {
    if (source != null) {
        ContextAnchor.THREAD_CONTEXT.set(ctx);
        final Configuration config = ConfigurationFactory.getInstance().getConfiguration(source);
        LOGGER.debug("Starting LoggerContext[name={}] from configuration {}", ctx.getName(), source);
        ctx.start(config);
        ContextAnchor.THREAD_CONTEXT.remove();
    } else {
        ctx.start();
    }
}
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.status.StatusLogger;

// In an XML configuration you can just use <Configuration status="TRACE"...
// Here we use less elegant code to switch on status logging 
// since we're not sure where things break down.
System.setProperty("log4j2.disable.jmx", "true");
StatusLogger status = StatusLogger.getLogger();
status.clear(); // remove old listeners that may prevent status output
status.setLevel(Level.TRACE);

// now configure log4j2...
// This should generate trace-level debug output to the console.
try (InputStream configStream = new ByteArrayInputStream(writer.toString().getBytes())) {            
    ConfigurationSource configurationSource = new ConfigurationSource(configStream);
    Configurator.initialize(null, configurationSource);
}