Log4J2 - 在运行时指定文件的appender文件名(Log4J2 - assigning

2019-07-19 20:47发布

我在类路径中的log4j2.xml配置文件。 其中一个附加目的地是一个文件的appender,我想在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年2月13日15:36:37574 DEBUG调用的类org.apache.logging.log4j.core.appender.FileAppender createAppender与params元素文件(文件名= “$ {SYS:LOGFILENAME}”,追加= “空”中,锁定= “空”,名字= “MyFile的”,immediateFlush = “空”,suppressExceptions = “空”,bufferedIO = “空”,的PatternLayout(% - 4R%d {YYYY-MM-DD / HH:MM:SS .SSS / ZZZ} [%T]%-5level%记录器36 {} - %MSG%N),null)的

2013年2月13日15:36:37576 DEBUG启动文件管理器$ {SYS:LOGFILENAME}

我怎么能有“文件名”的文件的Appender值在运行时进行设置? 另外,我怎么能只是一个新的文件追加程序添加到在运行时的根记录? 在Log4j的2.0大多数API的改变配置是隐藏的。

Answer 1:

H / T rgoers作为当附加目的地启动文件被打开的FileAppender不支持文件名两个美元符号。 你所表示与两个美元符号是你想要的 - 潜在的 - 每个事件不同的文件名。

随着单个$(如${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.setProperty("logFilename", filename);

重新配置记录仪:

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

这产生所需的行为。



Answer 2:

我知道这个话题是旧的,但答案并没有真正适合我。 下面是一个函数,它可以让你在运行时重新配置现有的Appender:

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();
}

你可以指定一个文件名,您的appender的名称和要记录的包名。

例如记录器:

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

可以重新配置调用是这样的:

updateLogger("log/api_new.log", "fileWriter_api", "my.package");


Answer 3:

由于log4j2 2.5版这里是实现这一目标的最简单的方法:

在您的log4j2.xml

<Appenders>
   <File name="MyFile" filename="${sys:logFilename}">
   ...

在你主MyApp.java文件

public class MyApp {

    Logger log;

    static {
          System.setProperty("logFilename", ...);
          log = LogManager.getLogger();
    }

    public static void main(String... args) {...}
}

美中不足的是:你应该设置logFilename系统属性之前log4j2被加载。 在之前调用这个例子LogManager.getLogger



文章来源: Log4J2 - assigning file appender filename at runtime