Java 设置日志文件名以在 Log4j 中包含当前日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/192456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:08:33  来源:igfitidea点击:

Setting a log file name to include current date in Log4j

java.netlogginglog4netlog4j

提问by Tim

I would like to set the log file name for a log4j and log4net appender to have the current date. We are doing Daily rollovers but the current log file does not have a date. The log file name format would be

我想为 log4j 和 log4net appender 设置日志文件名以具有当前日期。我们正在做每日翻转,但当前的日志文件没有日期。日志文件名格式为

logname.2008-10-10.log

Anyone know the best way for me to do this?

有人知道我这样做的最佳方法吗?

edit: I forgot to mention that we would want to do this in log4net as well. Plus any solution would need to be usable in JBoss.

编辑:我忘了提到我们也希望在 log4net 中执行此操作。另外,任何解决方案都需要在 JBoss 中可用。

采纳答案by gedevan

DailyRollingFileAppender is what you exactly searching for.

DailyRollingFileAppender 正是您要搜索的内容。

<appender name="roll" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="File" value="application.log" />
    <param name="DatePattern" value=".yyyy-MM-dd" />
    <layout class="org.apache.log4j.PatternLayout"> 
      <param name="ConversionPattern" 
          value="%d{yyyy-MMM-dd HH:mm:ss,SSS} [%t] %c %x%n  %-5p %m%n"/>
    </layout>
  </appender>

回答by matt b

I'm 99% sure that RollingFileAppender/DailyRollingFileAppender, while it gives you the date-rolling functionality you want, doesn't have any way to specify that the current log file should use the DatePatternas well.

我 99% 确定 RollingFileAppender/DailyRollingFileAppender 虽然它为您提供了您想要的日期滚动功能,但无法指定当前日志文件也应该使用它DatePattern

You might just be able to simply subclass RollingFileAppender (or DailyRollingFileAppender, I forget which is which in log4net) and modify the naming logic.

您可能只能简单地将 RollingFileAppender(或 DailyRollingFileAppender,我忘记在 log4net 中是哪个)子类化并修改命名逻辑。

回答by James A. N. Stauffer

I have created an appender that will do that. http://stauffer.james.googlepages.com/DateFormatFileAppender.java

我已经创建了一个可以做到这一点的 appender。 http://stauffer.james.googlepages.com/DateFormatFileAppender.java

/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.  */

package sps.log.log4j;

import java.io.IOException;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.*;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;

/**
 * DateFormatFileAppender is a log4j Appender and extends 
 * {@link FileAppender} so each log is 
 * named based on a date format defined in the File property.
 *
 * Sample File: 'logs/'yyyy/MM-MMM/dd-EEE/HH-mm-ss-S'.log'
 * Makes a file like: logs/2004/04-Apr/13-Tue/09-45-15-937.log
 * @author James Stauffer
 */
public class DateFormatFileAppender extends FileAppender {

  /**
   * The default constructor does nothing.
   */
  public DateFormatFileAppender() {
  }

  /**
   * Instantiate a <code>DailyRollingFileAppender</code> and open the
   * file designated by <code>filename</code>. The opened filename will
   * become the ouput destination for this appender.
   */
  public DateFormatFileAppender (Layout layout, String filename) throws IOException {
    super(layout, filename, true);
  }

  private String fileBackup;//Saves the file pattern
  private boolean separate = false;

  public void setFile(String file) {
    super.setFile(file);
    this.fileBackup = getFile();
  }

  /**
   * If true each LoggingEvent causes that file to close and open.
   * This is useful when the file is a pattern that would often
   * produce a different filename.
   */
  public void setSeparate(boolean separate) {
    this.separate = separate;
  }

  protected void subAppend(LoggingEvent event) {
    if(separate) {
        try {//First reset the file so each new log gets a new file.
            setFile(getFile(), getAppend(), getBufferedIO(), getBufferSize());
        } catch(IOException e) {
            LogLog.error("Unable to reset fileName.");
        }
    }
    super.subAppend(event);
  }


  public
  synchronized
  void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
                                                            throws IOException {
    SimpleDateFormat sdf = new SimpleDateFormat(fileBackup);
    String actualFileName = sdf.format(new Date());
    makeDirs(actualFileName);
    super.setFile(actualFileName, append, bufferedIO, bufferSize);
  }

  /**
   * Ensures that all of the directories for the given path exist.
   * Anything after the last / or \ is assumed to be a filename.
   */
  private void makeDirs (String path) {
    int indexSlash = path.lastIndexOf("/");
    int indexBackSlash = path.lastIndexOf("\");
    int index = Math.max(indexSlash, indexBackSlash);
    if(index > 0) {
        String dirs = path.substring(0, index);
//        LogLog.debug("Making " + dirs);
        File dir = new File(dirs);
        if(!dir.exists()) {
            boolean success = dir.mkdirs();
            if(!success) {
                LogLog.error("Unable to create directories for " + dirs);
            }
        }
    }
  }

}

回答by Lars Corneliussen

I don't know if it is possible in Java, but in .NET the property StaticLogFileName on RollingFileAppender gives you what you want. The default is true.

我不知道在 Java 中是否可行,但在 .NET 中,RollingFileAppender 上的属性 StaticLogFileName 为您提供了您想要的。默认值为真。

<staticLogFileName value="false"/>

Full config:

完整配置:

<appender name="DefaultFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="application"/>
  <staticLogFileName value="false"/>
  <appendToFile value="true" />
  <rollingStyle value="Date" />
  <datePattern value="yyyy-MM-dd&quot;.log&quot;" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
  </layout>
</appender>

&quot;.log&quot;is for not letting the dateformat recognice the global date pattern 'g' in log.

&quot;.log&quot;是为了不让 dateformat 识别日志中的全局日期模式“g”。

回答by shinds

Using log4j.properties file, and including apache-log4j-extras1.1 in my POM with log4j 1.2.16

使用 log4j.properties 文件,并使用 log4j 1.2.16 在我的 POM 中包含apache-log4j-extras1.1

log4j.appender.LOGFILE=org.apache.log4j.rolling.RollingFileAppender
log4j.appender.LOGFILE.RollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy
log4j.appender.LOGFILE.RollingPolicy.FileNamePattern=/logs/application_%d{yyyy-MM-dd}.log

回答by codder

this example will be creating logger for each minute, if you want to change for each day change the DatePatternvalue.

此示例将为每分钟创建记录器,如果您想为每一天更改DatePattern值,请更改该值。

<appender name="ASYNC" class="org.apache.log4j.DailyRollingFileAppender">
   <param name="File" value="./applogs/logger.log" />
   <param name="Append" value="true" />
   <param name="Threshold" value="debug" />
   <appendToFile value="true" />
   <param name="DatePattern" value="'.'yyyy_MM_dd_HH_mm"/>
   <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
      <param name="fileNamePattern" value="./applogs/logger_%d{ddMMMyyyy HH:mm:ss}.log"/>
      <param name="rollOver" value="TRUE"/>
   </rollingPolicy>
   <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{ddMMMyyyy HH:mm:ss,SSS}^[%X{l4j_mdc_key}]^[%c{1}]^ %-5p %m%n" />
   </layout>
</appender>
<root>
   <level value="info" />
   <appender-ref ref="ASYNC" />
</root>

回答by romeara

As a response to the two answers which mention DailyRollingFileAppender (sorry, I don't have enough rep to comment on them directly, and I think this needs to be mentioned), I would warn that unfortunately the developers of that class have documented that it exhibits synchronization and data loss, and recommend that alternatives should be pursued for new deployments.

作为对提到 DailyRollingFileAppender 的两个答案的回应(抱歉,我没有足够的代表直接对它们发表评论,我认为需要提及这一点),我会警告说,不幸的是,该课程的开发人员已经记录了它表现出同步和数据丢失,并建议应为新部署寻求替代方案。

DailyRollingFileAppender JavaDoc

DailyRollingFileAppender JavaDoc

回答by SANN3

You can set FileAppenderdynamically

您可以动态设置FileAppender

SimpleLayout layout = new SimpleLayout();           
FileAppender appender = new FileAppender(layout,"logname."+new Date().toLocaleString(),false);
logger.addAppender(appender); 

回答by rpajaziti

Even if u use DailyRollingFileAppender like @gedevan suggested, u will still get logname.log.2008-10-10(After a day, because the previous day log will get archived and the date will be concatenated to it's filename). So if u want .log at the end, u'll have to do it like this on the DatePattern:

即使你像@gedevan 建议的那样使用 DailyRollingFileAppender,你仍然会得到logname.log.2008-10-10(一天后,因为前一天的日志将被归档,日期将被连接到它的文件名)。所以如果你想要 .log 最后,你必须在 DatePattern 上这样做:

log4j.appender.file.DatePattern='.'yyyy-MM-dd-HH-mm'.log'

log4j.appender.file.DatePattern='.'yyyy-MM-dd-HH-mm'.log'