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

73

我想要设置log4j和log4net的appender日志文件名为当前日期。我们每天都进行滚动,但当前的日志文件没有日期。日志文件名格式应该是

logname.2008-10-10.log

有人知道我最好的方法吗?

编辑:我忘了提到我们还想在log4net中这样做。此外,任何解决方案都需要在JBoss中可用。

11个回答

56

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>

34
这会创建一个名为"application.log"的日志文件,并仅在滚动日志文件中放置日期模式,对原意不做改变,通俗易懂。 - Tim
5
因此,您将每天获得一个单独的日志文件。但是今天的日志文件将被命名为application.log,没有日期。在大多数情况下,这是可以接受的。 - gedevan
2
关于“DatePattern”的两个注释:
  • 我使用“.yyyy-MM-dd.lo\g”来获取所有日志文件相同的扩展名。
  • 在“g”之前需要加上反斜杠(至少对于log4net而言),以防止.NET应用预定义的“g”格式。
- gyrolf
2
@gyrolf,按照您提到的格式,您的日志最终会变成mylog.log.yyyy-MM-dd.log吗?还是您在某种程度上删除了先前的扩展名? - James McMahon
3
根据log4j文档:观察到DailyRollingFileAppender存在同步问题和数据丢失。(http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/DailyRollingFileAppender.html)。您应该真正遵循@shinds的建议。 - keisar
显示剩余2条评论

49

我使用log4j.properties文件,并在我的POM中包含了log4j 1.2.16和apache-log4j-extras 1.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

3
log4j.appender.out.RollingPolicy.FileNamePattern=logs/%d{yyyy-MM-dd HH-mm-ss} cron-script-x/out.loglog4j.appender.err.RollingPolicy.FileNamePattern=logs/%d{yyyy-MM-dd HH-mm-ss} cron-script-x/err.log这是两行Log4j配置代码,用于定义日志文件的命名规则和路径。第一行配置了输出日志的文件名格式为“logs/年-月-日 时-分-秒 cron-script-x/out.log”,第二行配置了错误日志的文件名格式为“logs/年-月-日 时-分-秒 cron-script-x/err.log”。 - Alex
目前,下载镜像链接都已经失效。您仍然可以在存档库中找到该库:http://archive.apache.org/dist/logging/log4j/companions/extras - mmutilva
log4j.appender..DatePattern=yyyy-MM-dd就可以解决问题。文件名每天都会滚动,不需要额外的依赖。 - vsingh

12

我99%确定 RollingFileAppender/DailyRollingFileAppender 提供了你想要的日期滚动功能,但是没有任何方法可以指定当前日志文件也应该使用 DatePattern

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


11

我不知道在Java中是否可能,但在.NET中,RollingFileAppender的StaticLogFileName属性可以实现您想要的功能。 默认值为true。

<staticLogFileName value="false"/>

完整配置:

<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; 的作用是防止日期格式中的全局日期模式 'g' 被日志识别。


仅供澄清:在yyyy-MM-dd&quot;.log&quot;中,HTML实体&quot是否应该存在,而不是' - chrki

11

我已经创建了一个可以做到这一点的 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);
            }
        }
    }
  }

}

2

这个示例将为每分钟创建一个记录器,如果您想改为每天更改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>

2
作为对提到 DailyRollingFileAppender 的两个回答的回应(很抱歉,我没有足够的声望直接评论它们,而且我认为这需要被提到),我要警告说不幸的是,该类的开发人员已经记录下它表现出同步和数据丢失,并推荐在新的部署中寻求替代方案。 DailyRollingFileAppender JavaDoc

2
你可以动态设置 FileAppender
SimpleLayout layout = new SimpleLayout();           
FileAppender appender = new FileAppender(layout,"logname."+new Date().toLocaleString(),false);
logger.addAppender(appender); 

在文件名中小心斜杠“/”。我宁愿使用:"logname"+new Date().format("yyyy-mm-dd-hh-MM")+".log" - Cléssio Mendes
2
这将仅在应用程序启动时创建新的日志文件,并且不会按日期将您的日志切割成文件。 - Mr. Cat

1
只需使用TimeBasedRollingPolicy,不要使用参数名为“File”。
  <appender name="pdi-execution-appender" class="org.apache.log4j.rolling.RollingFileAppender">   
        <!-- The active file to log to; this example is for Pentaho Server.-->
        <param name="Append" value="true" />
        <param name="Threshold" value="INFO"/>
        <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
            <!-- See javadoc for TimeBasedRollingPolicy -->
            <param name="FileNamePattern" value="logs/ETL-LogFile.%d{yyyyMMdd}.log" />
        </rollingPolicy>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value='%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t] %m'/>
        </layout>
  </appender>

0

你可以通过编程来实现:

        String dateFile = LocalDate.now().toString() + ".log";
        Enumeration enm = Logger.getRootLogger().getAllAppenders();
        Appender appender = null;
        while(enm.hasMoreElements()){
            appender = (Appender)enm.nextElement();
            String c = appender.getClass().toString();
            if(c.contains("FileAppender")){
                String f = ((FileAppender)appender).getFile();
                ((FileAppender)appender).setFile(f+dateFile);
                System.out.println("From:"+f+" to:"+dateFile);
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接