如何在 log4j.xml 的附加程序中给出动态文件名

发布于 2024-09-01 19:32:41 字数 668 浏览 7 评论 0原文

我正在使用 log4j 来记录信息。我使用了 log4j.xml 文件来创建日志文件。我已将每个日志文件的绝对路径作为 param 标记值给出。

例如:

<appender name="FA" class="org.apache.log4j.DailyRollingFileAppender">
  <param name="DatePattern" value="'_'yyyyMMdd"/>
  <param name="File" value="D:/logFiles/GPreprocessor.log"/>
  <layout class="com.dnb.genericpreprocessor.common.log.AppXMLLayout"/>
</appender>

我不想直接写“GPreprocessor.log”。实际上,该文件名是动态的,基于我的项目名称。例如,如果我运行程序 ABC.java,日志记录应转到 D:/logFiles/ABC.log,但如果我运行 XYZ.java,日志记录应转到 D:/ logFiles/XYZ.log。文件的位置将始终保持不变:D:/logFiles/。如何动态更改日志文件的名称?

I am using log4j to log information. I have used a log4j.xml file for creating log files. I have given the absolute path for each log file as a param tag value.

E.g.:

<appender name="FA" class="org.apache.log4j.DailyRollingFileAppender">
  <param name="DatePattern" value="'_'yyyyMMdd"/>
  <param name="File" value="D:/logFiles/GPreprocessor.log"/>
  <layout class="com.dnb.genericpreprocessor.common.log.AppXMLLayout"/>
</appender>

I do not want to write "GPreprocessor.log" directly. Actually, that file name is dynamic, based on my project's name. For example, if I run the program ABC.java, logging should go to D:/logFiles/ABC.log, but if I run XYZ.java, logging should go to D:/logFiles/XYZ.log. The file's location will always remain the same: D:/logFiles/. How can I change the log file's name dynamically?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

失去的东西太少 2024-09-08 19:32:41

执行以下操作要容易得多:

在 log4j.xml 中将变量定义为 ${variable}:

<appender name="FILE" class="org.apache.log4j.FileAppender">    
    <param name="File" value="${logfilename}.log" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d::[%t]::%-5p::%c::%x - %m%n" />
    </layout>       
</appender>

然后确保在启动 JVM 时设置系统属性,例如:

java -Dlogfilename=my_fancy_filename  example.Application

这将创建一个动态日志文件名:my_fancy_filename。或者

,您可以在代码中设置系统属性,只要在创建记录器之前执行此操作即可(例如,如果您希望在日志中包含 PID,则这很有用)。例如:

System.setProperty("logfilename", "a_cool_logname");

一旦设置完毕,您就可以继续正常获取记录器,它们将记录到动态文件(请注意那些在主方法执行之前创建记录器的静态记录器)。

It's much easier to do the following:

In log4j.xml define variable as ${variable}:

<appender name="FILE" class="org.apache.log4j.FileAppender">    
    <param name="File" value="${logfilename}.log" />
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d::[%t]::%-5p::%c::%x - %m%n" />
    </layout>       
</appender>

Then make sure you set the system property when you start your JVM such as:

java -Dlogfilename=my_fancy_filename  example.Application

That will create a dynamic log file name: my_fancy_filename.log

Alternatively, you can set the system property in code so long as you do it before you create a logger (this is useful if you want your PID in your logs for instance). Such as:

System.setProperty("logfilename", "a_cool_logname");

Once that is set you can go ahead and get your loggers as normal and they will log to the dynamic file (be careful of those static Loggers that create loggers before your main method executes).

執念 2024-09-08 19:32:41

下面是我使用 Log4J 动态生成文件名的代码。
它根据输入文件名和当前日期时间更改其名称。 (如果您多次运行同一个文件,这非常有用。)

public class LogClass {

    private static Logger log =  Logger.getLogger(LogClass.class);
    private static boolean initializationFlag = false;
    private static String fileName;

    private static void intializeLogger(){
        log.setLevel(Level.DEBUG);

        DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        Date date = new Date();

        RollingFileAppender appender = new RollingFileAppender();
        appender.setAppend(true);
        appender.setMaxFileSize("1MB");
        appender.setMaxBackupIndex(1);
        appender.setFile(fileName + "_" + dateFormat.format(date) + ".log");
        appender.activateOptions();

        PatternLayout layOut = new PatternLayout();
        layOut.setConversionPattern("%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n");
        appender.setLayout(layOut);

        log.addAppender(appender);
    }

    public static Logger getLogger(){
        if(initializationFlag == false){
            intializeLogger();
            initializationFlag = true;
            return LogClass.log;
        }
        else{
            return LogClass.log;
        }
    }

    public static void setFileName(String fileName){
        LogClass.fileName = fileName;
    }
}

现在,每当您想在程序中使用记录器时,
只需写下这两行:

LogClass.setFileName(yourFileName);
LogClass.getLogger().debug("hello!!");

快乐编码。

Below is my code for using Log4J for dynamically generate filename.
It changes its name according to input file name and current date-time. (So helpful in case you run same file multiple times.)

public class LogClass {

    private static Logger log =  Logger.getLogger(LogClass.class);
    private static boolean initializationFlag = false;
    private static String fileName;

    private static void intializeLogger(){
        log.setLevel(Level.DEBUG);

        DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
        Date date = new Date();

        RollingFileAppender appender = new RollingFileAppender();
        appender.setAppend(true);
        appender.setMaxFileSize("1MB");
        appender.setMaxBackupIndex(1);
        appender.setFile(fileName + "_" + dateFormat.format(date) + ".log");
        appender.activateOptions();

        PatternLayout layOut = new PatternLayout();
        layOut.setConversionPattern("%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n");
        appender.setLayout(layOut);

        log.addAppender(appender);
    }

    public static Logger getLogger(){
        if(initializationFlag == false){
            intializeLogger();
            initializationFlag = true;
            return LogClass.log;
        }
        else{
            return LogClass.log;
        }
    }

    public static void setFileName(String fileName){
        LogClass.fileName = fileName;
    }
}

Now whenever you want to use logger in your program,
Just write these two lines :

LogClass.setFileName(yourFileName);
LogClass.getLogger().debug("hello!!");

Happy Coding.

ぃ双果 2024-09-08 19:32:41

使用您自己的类扩展 FileAppender 更有意义,您可以在其中重写 setOptions() 方法。然后在您的 log4j.properties 中配置 root 来登录到 yourpackage.yourFileAppender ,这样就干净多了。

It makes more sense to extend FileAppender with your own class, in which you override setOptions() method. Then in your log4j.properties you configure root to log to yourpackage.yourFileAppender, which is much cleaner.

怼怹恏 2024-09-08 19:32:41

在包含 main 方法的类中,将类的名称设置为某个系统属性。在下面的示例中,我使用 log_dir 作为属性名称。

class ABC{
 public static void main(String s[]){
  System.setProperty("log_dir", ABC.class.getSimpleName());
 }
}

在您的 log4j.xml 文件中使用 File param 的 value 属性中的 log_dir 属性

<appender name="FA" class="org.apache.log4j.DailyRollingFileAppender">
  <param name="DatePattern" value="'_'yyyyMMdd"/>
  <param name="File" value="D:/logFiles/${log_dir}"/>
  <layout class="com.dnb.genericpreprocessor.common.log.AppXMLLayout"/>
</appender>

In your class containing main method set the name of your class to some system property. In following example I used log_dir as property name.

class ABC{
 public static void main(String s[]){
  System.setProperty("log_dir", ABC.class.getSimpleName());
 }
}

And in your log4j.xml file use log_dir property in File param's value attribute

<appender name="FA" class="org.apache.log4j.DailyRollingFileAppender">
  <param name="DatePattern" value="'_'yyyyMMdd"/>
  <param name="File" value="D:/logFiles/${log_dir}"/>
  <layout class="com.dnb.genericpreprocessor.common.log.AppXMLLayout"/>
</appender>

Works like a charm

德意的啸 2024-09-08 19:32:41

在执行任何操作之前,log4j 会彻底检查 log4j.xml 配置文件的类路径。假设,如果您在项目中引用的库 jar 中有任何 log4j.xml 配置文件,则 log4j 会加载该文件作为配置文件并开始记录日志。在这种情况下,当您按照 @Big B 的建议通过从系统属性获取值来动态设置 FileAppender 中的日志文件位置时,它将不起作用,因为 log4j 已经加载了它首先发现的配置文件。

为了防止这种情况,您可以使用 DOMConfigurator 来通知 log4j 它应该加载什么配置文件以及何时加载。因此,一旦您在程序中设置了 LogFileLocation 的系统属性,就可以使用 DOMConfigurator 按以下方式加载所需的属性文件:

System.setProperty("LogFileLocation", "D:Test/Logdetails"));
DOMConfigurator.configure("log4j.xml");

通过这种方式,您将在程序中设置系统属性 LogFileLocation 后加载 log4j.xml。 (它还将覆盖已加载的配置)

在 log4j.xml 配置中,您可以在参数标记“File”中设置文件位置:

<appender name="fileAppender"
        class="org.apache.log4j.FileAppender">
        <param name="File" value="${LogFileLocation}.log" />
        <param name="Append" value="false" /> 
<!-- false will make the log to override the file. true will make the log to append to the file -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                value="%d{dd/MM/yyyy HH:mm:ss} %-5p %c{2} 
        - %m%n" />
        </layout>
    </appender>

为了更好地理解我所说的内容,请提供 -Dlog4j.debug=true 在您的 VM 参数中,并在控制台中查看 log4j 执行的日志。

Before executing anything, log4j thoroughly checks the class path for log4j.xml configuration file. Let'say, by chance, if there is any log4j.xml configuration file in the library jars you referenced in your project, log4j loads that file as the configuration file and starts logging. In this context, when you are setting log file location in your FileAppender dynamically by getting the value from System properties as suggested by @Big B, it will not work since log4j had already loaded the configuration file it discovered first.

To prevent this, you can use DOMConfigurator to inform log4j what configuration file it should load and when it should load. So, as soon as you set the system property of LogFileLocation in your program use DOMConfigurator to load intended properties file in the following way:

System.setProperty("LogFileLocation", "D:Test/Logdetails"));
DOMConfigurator.configure("log4j.xml");

By doing this way, you will load log4j.xml after you set the system property LogFileLocation in your program. (It will also override the already loaded configuration)

Inside the log4j.xml configuration, you set the file location in the param tag 'File':

<appender name="fileAppender"
        class="org.apache.log4j.FileAppender">
        <param name="File" value="${LogFileLocation}.log" />
        <param name="Append" value="false" /> 
<!-- false will make the log to override the file. true will make the log to append to the file -->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                value="%d{dd/MM/yyyy HH:mm:ss} %-5p %c{2} 
        - %m%n" />
        </layout>
    </appender>

To understand whatever I said better, provide -Dlog4j.debug=true in your VM arguments and see the log of log4j execution in your console.

爱冒险 2024-09-08 19:32:41

对我来说,它仅在我使用 ${sys: ... 后才起作用,如下所示。如果没有它,它就不会拾取 java 命令中设置的变量。

<param name="File" value="${sys:logfilename}.log" />

For me it worked only after I used ${sys: ... as below. Without that it was not picking up that variable set in java command.

<param name="File" value="${sys:logfilename}.log" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文