Log4j2初始化后配置FileAppender

时间:2016-04-27 13:33:12

标签: java logging log4j2

我在为=iif(Fields!calculationUnitsInitial.Value=0 OR Fields!Produced.Value=0,0, Sum(Fields!calculationUnitsInitial.Value)/Sum(Fields!Produced.Value)*100) 记录器配置新的FileAppender时遇到问题。问题是我只知道文件的路径我应该在应用程序启动后附加我的日志,所以我尝试按照这些说明here修改{{1之后的原始配置初始化。

我已经阅读了很多关于堆栈溢出的类似问题的答案,但大部分是针对早期log4j2版本的,并且不会工作,因为他们现在已经将配置导向的插件实现到log4j本身。 / p>

应用成功创建了日志文件,但不会向其写入任何内容。我故意将该测试日志消息放在log4j2级别上,以便我可以验证它与日志级别阈值或其他任何问题无关。

我对log4j2配置不熟悉,此时感觉有点迷失。

我的log4j文件(非常基本)如下所示:

ERROR

此外,这是应添加新log4j2.xml

的方法
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Properties>
        <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
             <PatternLayout pattern="${PATTERN}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

我的FileAppender方法,它首先要做的是尝试更改记录器配置以写入我想要的文件:

public static void initLogFile(String path, Level level) {
    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    final Configuration config = ctx.getConfiguration();
    Layout layout = PatternLayout.createDefaultLayout(config);
    Appender appender = FileAppender.createAppender(path, "false", "true",
            "RollingFile", "true", "false", "false", "8000", null, null,
            "false", null, config);
    appender.start();
    config.addAppender(appender);
    AppenderRef ref = AppenderRef.createAppenderRef("RollingFile", null,
            null);
    AppenderRef[] refs = new AppenderRef[] { ref };
    LoggerConfig loggerConfig = LoggerConfig.createLogger("false", level,
            "org.apache.logging.log4j", "true", refs, null, config, null);
    loggerConfig.addAppender(appender, null, null);
    config.addLogger("org.apache.logging.log4j", loggerConfig);
    ctx.updateLoggers();
    System.out.println("Logger initialized");
}

2 个答案:

答案 0 :(得分:2)

你是什么意思,你只知道应用程序启动后的路径?无论如何,您应始终能够使用Lookup来确定文件路径。如果将路径指定为应用程序的参数之一,则应该能够使用主参数查找。

要清楚,您的配置应该是:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
    <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
         <PatternLayout pattern="${PATTERN}"/>
    </Console>
    <File name="file" fileName="${main:--logFile}">
         <PatternLayout pattern="${PATTERN}"/>
    </File> 
</Appenders>
<Loggers>
    <Logger name="org.apache.logging.log4j" level="${main:--level}">
       <AppenderRef ref="file"/>
    </Logger>
    <Root level="debug">
        <AppenderRef ref="Console" />
    </Root>
</Loggers>

请注意,我已配置了文件追加器。您的示例代码正在创建File appender,但出于某种原因将其命名为“RollingFile”。

答案 1 :(得分:0)

我接受了这个答案,因为它与问题的标题相关严格。如果您要查看此帖子以获取帮助,请花点时间阅读@rgoers的答案,因为它可能是您正在寻找的内容。

所以这就是我最终如何做到的。将现有的空新记录器配置到我的log4j2.xml文件中(因为我不想在运行时创建新的记录器),我将在运行时修改它。

原始代码的问题是记录器的名称。如果您查看原始帖子,我正在创建一个名为&#34; org.apache.logging.log4j&#34;的新appender。

在我的主课上,当我检索了我要记录的记录器时,我得到了我的主类所在的包的默认记录器(com.jorge.myapp.business)。因此,此记录器正在接收所有日志请求,而我创建的新请求(org.apache.logging.log4j)并未接收任何日志请求。这就是为什么它不会将任何内容记录到我想要的文件中的原因,因为所有记录请求都转到其他记录器(com.jorge.myapp.business)。

我希望这对某人有所帮助,解释时有点令人困惑......下面有关我的课程和配置文件的更多信息:

修改配置文件log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Properties>
        <Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
             <PatternLayout pattern="${PATTERN}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" />
        </Root>
        <Logger name="com.jorge.myapp.business" level="debug">
        </Logger>

    </Loggers>
</Configuration>

这是初始化方法,它从xml文件中检索当前的log4j2配置,并修改添加新文件追加器的现有记录器

public static void initLogFile(String path, Level level){

    final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
    final Configuration config = ctx.getConfiguration();

    Layout layout = PatternLayout.createLayout(Constants.LOG_PATTERN, null, config, null, null, false, false, null, null);
    Appender appender = FileAppender.createAppender(path, "true", "true", "File", "true",
        "false", "false", null, layout, null, "false", null, config);
    appender.start();
    config.addAppender(appender);
    AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
    AppenderRef[] refs = new AppenderRef[] {ref};
    LoggerConfig loggerConfig = config.getLoggerConfig("com.jorge.myapp.business");
    loggerConfig.addAppender(appender, null, null);
    ctx.updateLoggers();
}

我使用了一些常量Constants.java类):

public static final String LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss} [%-5level] MyApp - %msg%n";

有关Log4j2如何实际运作的更多信息&#39;引擎盖下&#39;可以找到here,正如@rgoers所指出的那样。