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

com.amazon.redshift.logger.LogFileHandler Maven / Gradle / Ivy

The newest version!
package com.amazon.redshift.logger;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.amazon.redshift.util.GT;
import com.amazon.redshift.util.RedshiftException;
import com.amazon.redshift.util.RedshiftState;

public class LogFileHandler implements LogHandler {

  private static final int FILE_SIZE = 10 * 1024 * 1024; // 10 MB
	
  private static final int FILE_COUNT = 10;
  
  private static final String FILE_EXTENSION = ".log";
  
  private static final String FILE_EXTENSION_SEPERATOR = ".";
  
  private static final Pattern FILE_SIZE_PATTERN =
      Pattern.compile(
          "\\s*(\\d+)\\s*(k|g|m|)b?\\s*",
          Pattern.CASE_INSENSITIVE);

  private static final int BUFFER_SIZE = 8 * 1024;
  
  private File currentFile;

  private String fileName;

  private boolean isRotation = false;

  private String directory;

  private int maxFileSize;

  private int maxFileCount;

  private ArrayList rotationFileNames;
  
  private PrintWriter writer = null;
  
  private boolean flushAfterWrite;
  
  public LogFileHandler(String filename, 
  											boolean flushAfterWrite, 
  											String maxLogFileSize,
  											String maxLogFileCount) throws Exception
  {
      int separator = filename.lastIndexOf(File.separator);
      directory = filename.substring(0, separator);
      fileName = filename.substring(separator + 1);
      
      this.flushAfterWrite = flushAfterWrite;
      
      if (-1 != separator)
      {
          createDirectory();
      }
      
      createWriter(maxLogFileSize, maxLogFileCount);
  }
  
  @Override
  public synchronized void write(String message) throws Exception
  {
      writer.println(message);
      if (flushAfterWrite)
        writer.flush();
      if (isRotation)
      {
        writer.flush();
        if ((0 != maxFileSize) && (currentFile.length() >= maxFileSize))
        {
            closeFile();
            rotateFiles();
            openFile();
        }
      }
  }
  
  @Override
  public synchronized void close() throws Exception {
  	if (writer != null) {
  		writer.close();
  	}
  }

  @Override
  public synchronized void flush() {
  	if (writer != null) {
  		writer.flush();
  	}
  }
  
  private void createDirectory() throws RedshiftException
  {
      File directory = new File(this.directory);
      if (!directory.exists() && !directory.mkdir())
      {
        throw new RedshiftException(GT.tr("Couldn't create log directory {0}", directory),
            					RedshiftState.UNEXPECTED_ERROR);
      }
  }
  
  private void createWriter(String maxLogFileSize, String maxLogFileCount) throws Exception
  {
    String fullFilename = directory + File.separator + fileName;
    if ((null != fullFilename) && (0 != fullFilename.length()))
    {
      BufferedOutputStream outStream = new BufferedOutputStream(
      																			new FileOutputStream(fullFilename, true),
      																			BUFFER_SIZE);
      writer = new PrintWriter(outStream);
      updateLoggingFileSettings(maxLogFileSize, maxLogFileCount);
      
      return;
    }
    
    throw new Exception("Failed to create log writer");
  }
  
  private void updateLoggingFileSettings(String maxLogFileSize, String maxLogFileCount)
  {
      currentFile = new File(directory + File.separator + fileName);

      // Read "maxLogFileCount"
      maxFileCount =  getMaxFileCount(maxLogFileCount);

      // Read "maxLogFileSize"
      maxFileSize = getMaxFileSize(maxLogFileSize);

      if (maxFileCount > 1)
      {
          isRotation = true;
          String fileExt = FILE_EXTENSION;
          
          rotationFileNames = new ArrayList();
          if (fileName.contains(FILE_EXTENSION_SEPERATOR))
          {
              fileExt = fileName
                  .substring(fileName.lastIndexOf(FILE_EXTENSION_SEPERATOR), fileName.length());
              fileName = fileName.substring(0, fileName.lastIndexOf(FILE_EXTENSION_SEPERATOR));
          }
          
          rotationFileNames.add(directory + File.separator + fileName + fileExt);
          for (int i = 1; i < maxFileCount; i++)
          {
              // Name format: {basename}.{i}{.ext} : e.g. "redshift.1.log"
              rotationFileNames
                  .add(directory + File.separator + fileName + "." + i + fileExt);
          }
      }
  }
  
  private int getMaxFileSize(String maxLogFileSize)
  {
      int maxBytes = FILE_SIZE;
      if ((null == maxLogFileSize) || (maxLogFileSize.isEmpty()))
          return maxBytes;
      
      Matcher fileSizematcher = FILE_SIZE_PATTERN.matcher(maxLogFileSize);
      if (fileSizematcher.find())
      {
          try
          {
              maxBytes = Integer.valueOf(fileSizematcher.group(1)) *
                  						toMultiplier(fileSizematcher.group(2).toLowerCase());
          }
          catch (NumberFormatException e)
          {
          	writer.println(e.getMessage());
          	writer.flush();
          }
      }
      
      return maxBytes;
  }
  
  private int getMaxFileCount(String maxLogFileCount)
  {
  	int maxfileCount = FILE_COUNT;
  	
    if ((null != maxLogFileCount) 
    			&& (!maxLogFileCount.isEmpty()))
    {
        int fileCount = Integer.valueOf(maxLogFileCount);
        
        if (fileCount > 0)
        	maxfileCount = fileCount;
    }
      
    return maxfileCount;
  }
  
  private Integer toMultiplier(String sizeChar)
  {
      if (sizeChar.equals("g"))
      {
          return 1024 * 1024 * 1024;
      }
      else if (sizeChar.equals("m"))
      {
          return 1024 * 1024;
      }
      else if (sizeChar.equals("k"))
      {
          return 1024;
      }
      throw new NumberFormatException("Invalid file size unit.");
  }
  
  
  private boolean isOpen() {
  	return (writer != null);
  }
  
  private void openFile() throws FileNotFoundException
  {
      currentFile = new File(rotationFileNames.get(0));
      BufferedOutputStream outStream = new BufferedOutputStream(
										new FileOutputStream(rotationFileNames.get(0), true),
										BUFFER_SIZE);
      
      writer = new PrintWriter(outStream);
  }
  
  private void closeFile()
  {
      if (isOpen())
      {
          currentFile = null;
          if (null != writer)
          {
              writer.close();
          }
      }
  }
  
  private void rotateFiles() throws Exception
  {
      if(!(rotationFileNames.isEmpty()))
      	deleteOldestFile();
  }
  
  private void deleteOldestFile() throws IOException
  {
    String last = rotationFileNames.get(rotationFileNames.size() - 1);
    File file = new File(last);
    
    if (file.exists())
    {
        file.delete();
    }
    
    for (int i = rotationFileNames.size() - 2; i >= 0; i--)
    {
        File current;
        current = new File(rotationFileNames.get(i));
        if (current.exists())
        {
            File dest = new File(last);
            if (!current.renameTo(dest))
            {
                throw new IOException(
                    "can not rename file: " + current.getName() + " to: " + last);
            }
        }
        last = rotationFileNames.get(i);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy