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

com.cisco.oss.foundation.logging.appender.LogFileCompressor 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 org.apache.log4j.spi.ErrorCode;

import java.io.File;
import java.io.InterruptedIOException;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Responsible for compressing log files using a given compression algorithm,
 * adding checksums if specified.
 * 
 * @author Simon
 *         Park
 * @version 1.7
 */
final class LogFileCompressor implements Runnable, FileRollEventListener {

  private static final int QUEUE_LIMIT = 64;

  private final FoundationFileRollingAppender appender;

  private final AppenderRollingProperties properties;

  private Thread threadRef = null;
  private AtomicBoolean keepRunning;
  private final List queue;

  LogFileCompressor(final FoundationFileRollingAppender rollingAppender,
      final AppenderRollingProperties appenderRollingProperties) {
    super();
    this.appender = rollingAppender;
    this.properties = appenderRollingProperties;
    this.queue = new LinkedList();
	keepRunning=new AtomicBoolean();
	keepRunning.set(true);
  }

  public final void run() {
    LogLog.debug("Log file compressor started");
    try {
      while (this.isRunning() || !queueBelowMinSize()) {
        try {
          this.compressNext();
        } catch (InterruptedException e) {
          // game over
          Thread.currentThread().interrupt();
        } catch (InterruptedIOException e) {
          Thread.currentThread().interrupt();
        }
      }
    } catch (Exception e) {
      this.appender.getErrorHandler().error("Log file compressor failed", e,
          ErrorCode.GENERIC_FAILURE);
    }
    LogLog.debug("Log file compressor stopped");
  }

  /*
   * (non-Javadoc)
   * 
   * @see
   * org.apache.log4j.appender.FileRollEventListener#onFileRoll(org.apache.log4j
   * .appender.FileRollEvent)
   */
  public final void onFileRoll(final FileRollEvent fileRollEvent) {
    this.compress(fileRollEvent.getBackupFile());
  }

  /**
   * For test purposes only.
   * 
   * @return max files in the backup file queue
   */
  final int getQueueLimit() {
    return QUEUE_LIMIT;
  }

  /**
   * For test purposes only.
   * 
   * @return number of files remaining in the backup file queue
   */
  final int getQueueSize() {
    int size = 0;
    synchronized (this.queue) {
      size = this.queue.size();
      this.queue.notifyAll();
    }
    return size;
  }

  /**
   * For test purposes only.
   */
  final void waitForEmptyQueue() {
    this.waitForSizeQueue(0);
  }

  /**
   * For test purposes only.
   */
  final void waitForSizeQueue(final int queueSize) {
    synchronized (this.queue) {
      while (this.queue.size() > queueSize) {
        try {
          this.queue.wait(250L);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
        }
      }
      try {
        Thread.sleep(500L);
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
      this.queue.notifyAll();
    }
  }

  /**
   * Starts the compressor.
   */
  final void begin() {
    if (LogFileCompressionStrategy.existsFor(this.properties)) {
      final Thread thread = new Thread(this, "Log4J File Compressor");
      thread.setDaemon(true);
      thread.start();
      this.threadRef = thread;
    }
  }

  /**
   * Stops the compressor.
   */
  final void end() {
    final Thread thread = this.threadRef;
    this.keepRunning.set(false);
    if (thread != null) {
     // thread.interrupt();
      try {
        thread.join();
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }
    this.threadRef = null;
  }

  final void compress(final File file) {
    if (this.isRunning()) {
      synchronized (this.queue) {
        while (this.queue.size() > QUEUE_LIMIT) {
          if (this.properties.isCompressionBlocking()) {
            try {
              this.queue.wait(this.properties.getCompressionMaxWait());
            } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
              return; // stop
            }
          } else {
            this.queue.remove(0);
          }
        }
        this.queue.add(file);
        this.queue.notifyAll();
      }
    }
  }

  private boolean isRunning() {
  //  return (this.threadRef != null) ? (!this.threadRef.isInterrupted()) : false;
	  return this.keepRunning.get();
  }

  private boolean queueBelowMinSize() {
    boolean belowMinSize = false;
    synchronized (this.queue) {
      final int compressionMinQueueSize = this.properties
          .getCompressionMinQueueSize();
      if (compressionMinQueueSize > 0) {
        belowMinSize = (this.queue.size() < compressionMinQueueSize);
      } else {
        belowMinSize = this.queue.isEmpty();
      }
      this.queue.notifyAll();
    }
    return belowMinSize;
  }

  private void compressNext() throws InterruptedException,
      InterruptedIOException {
    if (this.queue != null) {
      File file = null;
      synchronized (this.queue) {
        while (this.queueBelowMinSize()) {
          this.queue.wait(this.properties.getCompressionMaxWait());
          if(!this.keepRunning.get()){
				return;
			}
        }
        file = (File) this.queue.remove(0);
        this.queue.notifyAll();
      }
      if (file != null) {
        this.doCompression(file);
      }
    }
  }

  private void doCompression(final File file) {
    if (FileHelper.getInstance().isWriteable(file)) {
      final LogFileCompressionStrategy compressionStrategy = LogFileCompressionStrategy
          .findCompressionStrategy(this.properties);
      if (compressionStrategy != null) {
        compressionStrategy.compress(file, this.properties);
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy