Установка имени файла журнала для включения текущей даты в Log4j

Я хотел бы установить имя файла журнала для log4j и log4net appender, чтобы иметь текущую дату. Мы делаем ежедневные опрокидывания, но текущий файл журнала не имеет даты. Формат имени файла журнала будет

logname.2008-10-10.log

Кто-нибудь знает лучший способ для меня сделать это?

edit: Я забыл упомянуть, что мы хотели бы сделать это и в log4net. Кроме того, любое решение должно использоваться в JBoss.

Ответ 1

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>

Ответ 2

Использование файла log4j.properties и включение apache-log4j-extras 1.1 в моем POM с log4j 1.2.16

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

Я на 99% уверен, что RollingFileAppender/DailyRollingFileAppender, в то время как он дает вам необходимую функцию свертывания даты, не имеет никакого способа указать, что текущий файл журнала должен также использовать DatePattern.

Возможно, вы просто сможете просто подклассировать RollingFileAppender (или DailyRollingFileAppender, я забыл, что есть в log4net) и изменить логику именования.

Ответ 4

Я создал приложение, которое сделает это. 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);
            }
        }
    }
  }

}

Ответ 5

Я не знаю, возможно ли это на Java, но в .NET свойство StaticLogFileName на RollingFileAppender дает вам то, что вы хотите. Значение по умолчанию - 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; заключается в том, чтобы не дать dateformat распознать глобальный шаблон даты 'g' в журнале.

Ответ 6

В ответ на два ответа, в которых упоминается DailyRollingFileAppender (извините, у меня недостаточно комментариев, чтобы прокомментировать их напрямую, и я думаю, что это нужно упомянуть), я бы предупредил, что, к сожалению, разработчики этого класса документировал, что он демонстрирует синхронизацию и потерю данных, и рекомендует использовать альтернативы для новых развертываний.

DailyRollingFileAppender JavaDoc

Ответ 7

Вы можете установить FileAppender динамически

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

Ответ 8

этот пример будет создавать регистратор для каждой минуты, если вы хотите изменить для каждого дня изменение значения 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>

Ответ 9

Даже если вы используете DailyRollingFileAppender, например, @gedevan, вы все равно получите logname.log.2008-10-10 (через день, потому что журнал предыдущего дня будет заархивирован, а дата будет объединена с ним именем файла). Так что, если вы хотите.log в конце, вам придется делать это так на DatePattern:

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