当前位置: 首页 > 知识库问答 >
问题:

Log4J2-在运行时分配文件appender文件名

梅飞宇
2023-03-14

我在类路径中有一个log4j2.xml配置文件。其中一个附加器是一个文件附加器,我想在Java应用程序的运行时设置目标文件名。

根据文档,我应该能够在log4j2.xml文件中使用双“$”和上下文前缀:

<appenders>
    <File name="MyFile" fileName="$${sys:logFilename}">
        <PatternLayout pattern="%-4r %d{${datestamp}} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>

其中“sys”前缀表示配置器将在系统属性中查找属性“logfilename”。所以在应用程序中,我调用(相当早的时候):

System.setProperty("logFilename", filename);

我还在xml文件中为log4j2打开了自动重新配置:

<configuration status="debug" monitorInterval="5">>

不幸的是,这没有任何影响,并且日志文件从未被创建。log4j2的部分状态输出如下:

2013-02-13 15:36:37,574调试在类org.apache.logging.log4j.core.appender.fileappender上调用带有参数的元素文件的createAppender(文件名=“${sys:logfilename}”,append=“null”,locking=“null”,name=“myfile”,immediateflush=“null”,suppressExceptions=“null”,bufferedio=“null”,PatternLayout(%-4r%d{yyyy-mm-dd/hh:mm:ss.sss

2013-02-13 15:36:37,576调试启动FileManager${sys:LogFileName}

如何在运行时设置文件附加器中的“filename”值?或者,我如何简单地在运行时向根记录器添加一个新的文件附加器?在Log4J2.0中,用于更改配置的大部分API都是隐藏的。

共有2个答案

沃驰
2023-03-14

我知道这个话题很老,但答案并不适合我。下面是一个函数,它允许您在运行时重新配置现有的附加程序:

static void updateLogger(String file_name, String appender_name, String package_name){
LoggerContext context = (LoggerContext) LogManager.getContext(false);
    Configuration configuration = context.getConfiguration();
    Layout<? extends Serializable> old_layout = configuration.getAppender(appender_name).getLayout();

    //delete old appender/logger
    configuration.getAppender(appender_name).stop();
    configuration.removeLogger(package_name);

    //create new appender/logger
    LoggerConfig loggerConfig = new LoggerConfig(package_name, Level.INFO, false);
    FileAppender appender = FileAppender.createAppender(file_name, "false", "false", appender_name, "true", "true", "true",
            "8192", old_layout, null, "false", "", configuration);
    appender.start();
    loggerConfig.addAppender(appender, Level.INFO, null);
    configuration.addLogger(package_name, loggerConfig);

    context.updateLoggers();
}

您可以指定一个文件名、追加器的名称和要记录的包名。

记录器示例:

<File name="fileWriter_api" fileName="${LOG_DIR}/api.log" append="false">
  <PatternLayout pattern="${PATTERN}"/>
</File>

可以通过如下调用重新配置:

updateLogger("log/api_new.log", "fileWriter_api", "my.package");
臧欣怿
2023-03-14

h/t rgoers文件附加器不支持文件名上有两个美元符号,因为在附加器启动时文件是打开的。您用两个美元符号表示的是,您希望每个事件都有一个不同的文件名。

使用单个$(如${sys:logfilename})时,系统将在系统属性中查找属性“logfilename”。

因此,log4j2.xml应该具有:

<appenders>
    <File name="MyFile" fileName="${sys:logFilename}">
        <PatternLayout pattern="%-4r %d{${datestamp}} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>

Java应用程序应设置system属性:

System.setProperty("logFilename", filename);

并重新配置记录器:

org.apache.logging.log4j.core.LoggerContext ctx =
    (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
ctx.reconfigure();

这将产生所需的行为。

 类似资料:
  • 我已经浏览了之前关于在运行时添加Log4j2附加器的线程,但没有一个真正适合我的场景。 我们将一个长时间运行的Flink作业打包到一个胖jar中,我们基本上将其提交给一个运行的Flink集群。我们想把错误日志转发给哨兵。很方便,Sentry提供了一个我希望能够使用的Log4j2 appender,但所有让Log4j2工作的尝试都失败了——对此有点疯狂(花了几天时间)。 因为Flink(也使用log

  • 我试着: 删除app.log,查看我的配置(d:\logs\app.log)是否有效。当我运行应用程序时,它会创建app.log,所以我认为这意味着它会看到配置,唯一的事情是它不会像我在java application中那样保存log.info 将根级别更改为“trace”,它将打印log.info. [编辑:] null 提前谢了。

  • 我使用log4j2.9 我在log4j2.xml中配置了文件追加器。 我在Runtiime找不到任何如何选择appender的例子。 你能给我举个简单的例子吗?

  • 我有下面的Log4J2配置XML: 但是,每当log4j2 appender写入文件时,它在写入指定的文件路径时不会使用正确的字符串。 log4j2 appender第一次写入文件时,会写入由指定的正确文件路径。但是,只要将具有另一个Id的员工的信息放入线程上下文中,appender仍然会记录到旧文件路径。 例如,appender第一次记录时,它会写入正确的路径: 但当记录器记录下一个员工Id(使

  • 最近,我决定学习如何使用log4j2记录器。我下载了所需的jar文件,创建了库,xml编译文件,并尝试使用它。不幸的是,我在console(Eclipse)中得到了这样的语句: 这是我的测试类代码: 和我的xml配置文件: 我还尝试使用不带标记的xml,以及包规范和各种文件夹/包目录,但没有帮助。现在我的文件直接位于Eclipse的project文件夹中。

  • 我正在使用log4j的现有系统上工作,我想更新到log4j2。 有一个自定义Springbean从文件加载配置。我需要保持这种方法。我不能使用"log4j.configuration文件"系统属性。 我们有一个属性文件,其中指定了当前log4j.xml的路径(NFS共享) Springbean有以下代码。。。 } 在log4j2中,没有PropertyConfiguration。如何加载log4j