0

我的公司使用一个软件包,它从我们的服务器读取日志文件,解析它们,并将性能数据输出到数据库中。我们无权修改读取文件的应用程序的源代码,但我们有权访问写入文件的代码。我需要更改日志文件的写入方式,并且我想使用 log4j(所以我可以使用 AsyncAppender)。该程序需要一些东西:

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

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

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

是否可以使用自定义 log4j 文件附加程序来满足上述要求?我查看了 DailyRollingFileAppender,但似乎无法弄清楚如何完全按照我的需要控制文件名。此外,我似乎无法弄清楚如何在生成日志时将第一行写入日志(例如,当新的日志文件滚入时,我可以注册一些回调函数)?

4

2 回答 2

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>    
于 2013-11-15T00:01:36.733 回答
0

我认为您可以通过以下方式实现前两个

使用RollingFileAppender并指定FixedWindowRollingPolicyRollingPolicy

至于#3,您始终可以编写自己的处理程序

于 2013-11-08T20:42:19.760 回答