2013-02-13 131 views
28

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

按照docs我应该能够使用双“$”,并在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); 

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

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

不幸的是,这无论如何没有任何效果,并且从不创建日志文件。一些log4j2状态输出的低于:

2013年2月13日15:36:37574 DEBUG上类org.apache.logging.log4j.core.appender.FileAppender调用createAppender用于与params元素文件(文件名=“null”,suppressExceptions =“null”,bufferedIO =“null”,PatternLayout(% - >“)”,append =“null”,locking =“null”,name =“MyFile” 4r%d {yyyy-MM-dd/HH:mm:ss.SSS/zzz} [%t]%-5级%logger {36} - %msg%n),null)

2013-02-13 15:36:37,576调试开始FileManager $ {sys:logFilename}

如何在运行时设置文件附加程序中“文件名”的值?或者,我怎样才能在运行时简单地将新的文件附加器添加到根记录器?在Log4j 2.0中,大部分改变配置的API都是隐藏的。

+0

做一个SO搜索。它已经被回答了: http://stackoverflow.com/questions/10699358/log4j-creating-modifying-appenders-at-runtime-log-file-recreated-and-not-appe – mightyrick 2013-02-13 20:51:53

+7

这是一个Log4j 2.0的问题,所以API与Log4j 1.2非常不同,以前答案中的很多方法都没有公开。 – user84756 2013-02-13 20:58:51

回答

30

h/t rgoers 当appender启动时打开文件时,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(); 

这会产生所需的行为。

+1

我不确定这是因为API改变了,但这对我没有用。为了实现这个目的,我必须做的是做'$ {sys:logFilename}' – rm5248 2013-08-22 20:20:49

+0

你是对的 - 这是原始答案中的拼写错误。现在更正。谢谢! – user84756 2013-08-23 20:25:32

+1

使用'2.0-beta9'版本和一个'$'这将创建两个文件,一个文件名称正确,但内容为空,另一个文件名为'$ {sys:logFilename} .log'。 – amoe 2013-12-11 11:02:01

7

自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) {...} 
} 

CATCH:,则应该设置logFilename加载log4j2之前的系统属性。在调用LogManager.getLogger之前的例子中。

+1

这不起作用,它只是创建'$ {sys/logFilename}'文件 – Akshay 2015-12-27 00:00:04

+0

这在我的命令行独立应用程序中工作。您可能会遇到问题,因为您依赖的其他代码会比您想象的更早地初始化log4j2。你能否描述你尝试这种环境?它是一个Web应用程序还是一个命令行工具? – 2015-12-27 02:34:43

+0

+1为警告!这是抓住。我试图做到这一点,但总是得到第二个空文件'$ {sys/logFilename}'。 – Chris 2016-08-25 21:32:48

6

我知道这个话题很旧,但答案并不适合我。下面是一个函数,它可以让你在运行时重新配置现有的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"); 
+0

这是一个很好的答案! – FrustratedWithFormsDesigner 2017-03-01 21:40:21

+0

这适用于指定的appender和包,但会停止所有其他appender。你有没有看到这个问题,你知道如何绕过它吗? – biggvsdiccvs 2017-05-31 06:59:55

+0

我忘了'loggerConfig.addAppender(appender,Level.INFO,null);'行中的leve.INFO规范,因为它会使通过此appender记录DEBUG或TRACE事件成为可能,即使您更改了记录器的日志级别。 – mitchnull 2018-02-22 08:01:03