如何创建log4j自定义appender并控制文件名

时间:2013-11-08 20:00:36

标签: java logging log4j

我公司使用的软件包从我们的服务器读取日志文件,解析它们,并将性能数据吐出到数据库中。我们没有访问/权限来修改读取文件的应用程序的源代码,但我们可以访问写入文件的代码。我需要改变日志文件的写入方式,我想使用log4j(所以我可以使用AsyncAppender)。该计划需要一些事项:

1)。应该有10个日志文件滚动,每个日志文件将是一天的日志。这些文件需要命名为0到9,我需要能够以编程方式设置文件名以及何时根据服务器时间滚动。

2)。基本上在生成第11个日志文件时,它应删除最旧的日志文件并开始写入该文件。

3)。生成新的日志文件时,我需要能够插入一个时间戳作为文件的第一行(System.currentTimeMillis())。

是否可以使用自定义log4j文件追加器满足上述要求?我看过DailyRollingFileAppender,但似乎无法弄清楚如何控制文件名完全像我需要的那样。此外,我似乎无法弄清楚如何在生成日志时在日志中写入第一行(例如,是否有一些回调函数,我可以在新日志文件滚入时注册)?

2 个答案:

答案 0 :(得分:0)

我认为你可以用

获得前2名

使用RollingFileAppender并为RollingPolicy

指定FixedWindowRollingPolicy

对于#3,你总是可以编写自己的处理程序

答案 1 :(得分:0)

为了子孙后代。我使用以下类作为我的自定义滚动策略

import org.apache.log4j.rolling.RollingPolicyBase;
import org.apache.log4j.rolling.RolloverDescription;
import org.apache.log4j.rolling.RolloverDescriptionImpl;
import org.apache.log4j.rolling.TriggeringPolicy;
import org.apache.log4j.Appender;
import org.apache.log4j.spi.LoggingEvent;

public final class CustomRollingPolicy extends RollingPolicyBase
implements TriggeringPolicy
{


private short curFileId = -1;
private String lastFileName = null;

static private final long FILETIMEINTERVAL = 86400000l;
static private final int NUM_FILES = 10;//86400000l;
public String folderName = "";

public String getFolderName() {
return folderName;
}

public void setFolderName(String folderName) {
    this.folderName = folderName;
}

private short calculateID(long startTime) {
    return (short) ((startTime / FILETIMEINTERVAL) % NUM_FILES);
}


 public String getCurrentFileName()
  {
      StringBuffer buf = new StringBuffer();
  buf.append(folderName);
  buf.append(calculateID(System.currentTimeMillis()));
  return buf.toString();
  }

  public void activateOptions()
  {
super.activateOptions();
this.lastFileName = getCurrentFileName();
  }

  public RolloverDescription initialize(String currentActiveFile, boolean append)
  {
    curFileId = this.calculateID(System.currentTimeMillis());
    lastFileName = getCurrentFileName();
    String fileToUse = activeFileName != null? activeFileName: currentActiveFile != null?currentActiveFile:lastFileName;
    return new RolloverDescriptionImpl(fileToUse, append, null, null);
  }

public RolloverDescription rollover(String currentActiveFile)
{
    curFileId = this.calculateID(System.currentTimeMillis());

    String newFileName = getCurrentFileName();
    if (newFileName.equals(this.lastFileName)) 
    {
        return null;
    }

    String lastBaseName = this.lastFileName;

    String nextActiveFile = newFileName;

    if (!currentActiveFile.equals(lastBaseName)) 
    {
        nextActiveFile = currentActiveFile;
    }

    this.lastFileName = newFileName;
    return new RolloverDescriptionImpl(nextActiveFile, false, null, null);
}

public boolean isTriggeringEvent(Appender appender, LoggingEvent event, String filename, long fileLength)
{
    short fileIdForCurrentServerTime = this.calculateID(System.currentTimeMillis());
    return curFileId != fileIdForCurrentServerTime;
}
}

这是我的log4j xml文件中的appender配置:

    <!-- ROLLING FILE APPENDER FOR RUM LOGS -->
    <appender name="rumRollingFileAppender" class="org.apache.log4j.rolling.RollingFileAppender">       
        <rollingPolicy class="com.ntrs.wpa.util.CustomRollingPolicy">
            <param name="folderName" value="C:/bea-portal-10.3.2/logs/"/>
        <param name="FileNamePattern" value="C:/bea-portal-10.3.2/logs/foo.%d{yyyy-MM}.gz"/>
    </rollingPolicy>        
    <layout class="com.ntrs.els.log4j.AppServerPatternLayout">
          <param name="ConversionPattern" value="%m%n" />
    </layout>
  </appender>