All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cisco.oss.foundation.logging.appender.AbstractRoller Maven / Gradle / Ivy

/*
 * Copyright 2015 Cisco Systems, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.cisco.oss.foundation.logging.appender;

import org.apache.log4j.helpers.FileHelper;
import org.apache.log4j.helpers.LogLog;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Base class for roller implementations, this has responsibility only for
 * performing the actual file roll. Subclasses have responsibility for deciding
 * whether a roll is required, and for computing the time used to perform the
 * roll.
 * 
 * @author Simon
 *         Park
 * @version 1.16
 */
abstract class AbstractRoller implements FileRollable {

  private static final class BackupFile {

    private final File baseFile;

    private final File timeSuffixedFile;

    private String backupCountSuffix = "";

    BackupFile(File logFile, String timeSuffix) {
      super();
      this.baseFile = logFile;
      this.timeSuffixedFile = new File(logFile.getAbsoluteFile() + timeSuffix);
    }

    void setBackupCountSuffix(String backupCountSuffix) {
      this.backupCountSuffix = backupCountSuffix;
    }

    File getBaseFile() {
      return this.baseFile;
    }

    File getTimeSuffixedFile() {
      return this.timeSuffixedFile;
    }

    File getBackupFile() {
      return new File(this.getTimeSuffixedFile().getPath() + '.'
          + this.backupCountSuffix);
    }
  }

  private final FoundationFileRollingAppender appender;

  private final AppenderRollingProperties properties;

  private final BackupSuffixHelper backupSuffixHelper;

  private final List fileRollEventListeners;

  AbstractRoller(final FoundationFileRollingAppender rollingAppender,
      final AppenderRollingProperties properties) {
    super();
    this.fileRollEventListeners = Collections.synchronizedList(new ArrayList());
    this.appender = rollingAppender;
    this.properties = properties;
    this.backupSuffixHelper = new BackupSuffixHelper(properties);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.apache.log4j.appender.FileRollEventSource#addFileRollEventListener(
   * org.apache.log4j.appender.FileRollEventListener)
   */
  public final void addFileRollEventListener(
      final FileRollEventListener fileRollEventListener) {
    this.fileRollEventListeners.add(fileRollEventListener);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.apache.log4j.appender.FileRollEventSource#removeFileRollEventListener
   * (org.apache.log4j.appender.FileRollEventListener)
   */
  public final void removeFileRollEventListener(
      final FileRollEventListener fileRollEventListener) {
    this.fileRollEventListeners.remove(fileRollEventListener);
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.apache.log4j.appender.FileRollEventSource#fireFileRollEvent(org.apache
   * .log4j.appender.FileRollEvent)
   */
  public final void fireFileRollEvent(final FileRollEvent fileRollEvent) {
    final Object[] listeners = this.fileRollEventListeners.toArray();
    for (int i = 0; i < listeners.length; i++) {
      final FileRollEventListener listener = (FileRollEventListener) listeners[i];
      listener.onFileRoll(fileRollEvent);
    }
  }

  public final FoundationFileRollingAppender getAppender() {
    return this.appender;
  }

  final AppenderRollingProperties getProperties() {
    return this.properties;
  }

  /**
   * Invoked by subclasses; performs actual file roll. Tests to see whether roll
   * is necessary have already been performed, so just do it.
   */
  final void roll(final long timeForSuffix) {

    final File backupFile = this.prepareBackupFile(timeForSuffix);

    // close filename
    this.getAppender().closeFile();

    // rename filename on disk to filename+suffix(+number)
    this.doFileRoll(this.getAppender().getIoFile(), backupFile);

    // setup new file 'filename'
    this.getAppender().openFile();

    this.fireFileRollEvent(new FileRollEvent(this, backupFile));
  }

  /**
   * Builds the file that the current log file will be renamed to, including the
   * base log file name, plus time part, plus backup counter suffix,
   * e.g. "base.log.2007-01-01.1".
   * 
   * @param timeForSuffix
   * @return The file to be used when performing the actual file roll.
   */
  private File prepareBackupFile(final long timeForSuffix) {
    final String timeSuffix = this.backupSuffixHelper
        .backupTimeAsString(timeForSuffix);
    final BackupFile backupFile = new BackupFile(
        this.getAppender().getIoFile(), timeSuffix);
    // read in a sorted list of log files (most recent first), filtered on
    // the suffix pattern
    final LogFileList logFileList = this.logFileListFilteredOn(backupFile);
    String backupCountSuffix = this.backupSuffixHelper
        .defaultBackupCountAsString();
    if (!logFileList.isEmpty()) {
      // file list not empty: numbering to be added to suffix.
      final File lastLogFile = logFileList.lastFile();
      // extract number appended to filename of last file in list
      backupCountSuffix = this.backupSuffixHelper.nextBackupCountAsString(
          lastLogFile.getName(), backupFile.getBaseFile());
    }
    backupFile.setBackupCountSuffix(backupCountSuffix);
    return backupFile.getBackupFile();
  }

  /**
   * @param backupFile
   * @return A list of log files that contain the base log file name plus the
   *         current time-based filename extension.
   */
  private LogFileList logFileListFilteredOn(final BackupFile backupFile) {
    LogLog.debug("Reading in list of existing log files");
    final String timeSuffixedFilename = backupFile.getTimeSuffixedFile()
        .getName();
    return new LogFileList(backupFile.getBaseFile(), new FilenameFilter() {

      public final boolean accept(final File logDir, final String name) {
        // select all files matching the current filename plus temporal suffix
        return name.startsWith(timeSuffixedFilename);
      }
    }, this.getProperties());
  }

  /**
   * Renames the current base log file to the roll file name.
   * 
   * @param from
   *          The current base log file.
   * @param to
   *          The backup file.
   */
  private void doFileRoll(final File from, final File to) {
    final FileHelper fileHelper = FileHelper.getInstance();
    if (!fileHelper.deleteExisting(to)) {
      this.getAppender().getErrorHandler()
          .error("Unable to delete existing " + to + " for rename");
    }
    final String original = from.toString();
    if (fileHelper.rename(from, to)) {
      LogLog.debug("Renamed " + original + " to " + to);
    } else {
      this.getAppender().getErrorHandler()
          .error("Unable to rename " + original + " to " + to);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy