Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Log4j2初始化后配置FileAppender_Java_Logging_Log4j2 - Fatal编程技术网

Java 在Log4j2初始化后配置FileAppender

Java 在Log4j2初始化后配置FileAppender,java,logging,log4j2,Java,Logging,Log4j2,我无法为我的log4j2记录器配置新的FileAppender。问题是,在应用程序启动后,我只知道应该添加日志的文件路径,因此我尝试在初始化日志4J2后按照这些说明修改原始配置 我已经阅读了很多关于堆栈溢出的类似问题的答案,但大多数都是针对早期的log4j版本的,并且不会起作用,因为他们现在已经在log4j中实现了面向配置的插件 应用程序成功地创建了日志文件,但不会向其中写入任何内容。我故意将测试日志消息放在错误级别上,这样我就可以验证它与日志级别阈值或其他问题无关 我对log4j2配置有点陌生

我无法为我的
log4j2
记录器配置新的
FileAppender
。问题是,在应用程序启动后,我只知道应该添加日志的文件路径,因此我尝试在初始化日志4J2后按照这些说明修改原始配置

我已经阅读了很多关于堆栈溢出的类似问题的答案,但大多数都是针对早期的
log4j
版本的,并且不会起作用,因为他们现在已经在log4j中实现了面向配置的插件

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

我对log4j2配置有点陌生,在这一点上有点不知所措

我的
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>
还有我的
Main
方法,它做的第一件事就是尝试更改记录器配置,以写入我想要的文件:

static final Logger log = LogManager.getLogger(Main.class.getName());
  public static void main( String[] args )
    {
        // Init
        System.out.println("Initializing logger");
        Utils.initLogFile("C:/Users/Jorge/Desktop/logtest/test.log", Level.DEBUG);

        log.error("test error message");

        ...
 }

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

为了清楚起见,您的配置应该如下所示:

<?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>

%d{yyyy-MM-dd HH:MM:ss}[%t]-5级别%logger{36}-%msg%n


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

我接受这个答案,因为它与问题的标题严格相关。如果你正在查看这篇文章寻求帮助,你应该花点时间阅读@rgoers的答案,因为它可能就是你想要的

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

我的原始代码的问题是记录器的名称。如果你看一下最初的帖子,我正在创建一个名为“org.apache.logging.log4j”的新appender

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

我希望这能帮助一些人,解释起来有点混乱。。。下面是有关我的类和配置文件的更多信息:

修改了config文件
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>
我使用了一些常量(
constants.java
class):


如@rgoers所指出的,可以找到有关Log4j2如何“在引擎盖下”实际工作的更多信息。

该应用程序的一个参数是日志文件路径。当任何用户通过命令行运行应用程序时,包含应用程序生成的所有日志的文件路径(实际上是一个可运行的JAR)作为参数传递。我在查找文件时没有遇到问题,我在写入普通配置的
文件追加器时遇到问题。不要动态配置文件追加器。将其添加到配置文件中。只需使用${main:--file}或文件的任何选项即可获得文件路径。如果出于某种原因,这对您不起作用,您可以创建自己的查找。但是我没有理由根据您的描述以编程方式配置appender。也许我的方式不是最好的,您是对的,我应该使用您建议的配置,但我很想知道为什么我创建的appender应该写入的日志文件在应用程序执行结束时是空的。。。我对新文件附加器的创建有什么误解?它没有记录任何东西,我不知道为什么。尽管如此,我还是会按照您的建议尝试解决这个问题,但我想理解为什么我的方法不起作用,可能是因为您正在创建的LoggerConfig名为org.apache.logging.log4j。您是否真的在该包下创建了任何记录器?这是非常值得怀疑的。事实上,就是这样!问题在于
org.apache.logging.log4j
。将其更改为向记录器发送请求的我的一个应用程序包,这样做了,并写入了该文件。。我仍然不明白记录器的名称与软件包有什么关系,但如果您能在另一个答案中解释,我将接受它,因为这是我所要求的解决方案。
<?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>
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();
}
public static final String LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss} [%-5level] MyApp - %msg%n";