avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-avalon-logkit/src/test/org/apache/log/output/test RevolvingFileStrategyTestCase.java
Date Fri, 29 Mar 2002 14:36:30 GMT
donaldp     02/03/29 06:36:30

  Modified:    src/java/org/apache/log/output/io/rotate
                        RevolvingFileStrategy.java
  Added:       src/java/org/apache/log/output/io/rotate
                        BaseFileNameFilter.java
               src/test/org/apache/log/output/test
                        RevolvingFileStrategyTestCase.java
  Log:
  Make it possible for the revolving strategy to search for the next rotation intelligently.
Either grabs the highest unused rotation or else if all rotations are used then it will use
the one after the youngest rotation.
  
  Revision  Changes    Path
  1.5       +180 -23   jakarta-avalon-logkit/src/java/org/apache/log/output/io/rotate/RevolvingFileStrategy.java
  
  Index: RevolvingFileStrategy.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-logkit/src/java/org/apache/log/output/io/rotate/RevolvingFileStrategy.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- RevolvingFileStrategy.java	27 Mar 2002 22:07:57 -0000	1.4
  +++ RevolvingFileStrategy.java	29 Mar 2002 14:36:30 -0000	1.5
  @@ -1,10 +1,3 @@
  -/*
  - * Copyright (C) The Apache Software Foundation. All rights reserved.
  - *
  - * This software is published under the terms of the Apache Software License
  - * version 1.1, a copy of which has been included with this distribution in
  - * the LICENSE file.
  - */
   package org.apache.log.output.io.rotate;
   
   import java.io.File;
  @@ -13,9 +6,17 @@
   import java.text.NumberFormat;
   
   /**
  - * Strategy for naming log files based on appending a revolving suffix.
  + * strategy for naming log files based on appending revolving suffix.
  + * If the initial rotation is not specified then the class will attempt to
  + * calculate the rotation number via the following algorithm.
  + *
  + * It will search for the file with the highest number in the rotation. It will
  + * then increment its rotation number and use that number. If all files in rotation
  + * are present then it will then set the initial rotation to the next rotation after
  + * the most recently created file.
    *
    * @author <a href="mailto:bh22351@i-one.at">Bernhard Huber</a>
  + * @author <a href="mailto:peter@apache.org">Peter Donald</a>
    */
   public class RevolvingFileStrategy
       implements FileStrategy
  @@ -35,6 +36,11 @@
       ///the base file name.
       private File m_baseFile;
   
  +    public RevolvingFileStrategy( final File baseFile, final int maxRotations )
  +    {
  +        this( baseFile, -1, maxRotations );
  +    }
  +
       public RevolvingFileStrategy( final File baseFile,
                                     final int initialRotation,
                                     final int maxRotations )
  @@ -45,23 +51,24 @@
           m_rotation = initialRotation;
           m_maxRotations = maxRotations;
   
  -        if( -1 == initialRotation )
  -        {
  -            ///TODO: Scan filesystem to get current number
  -        }
  -
           if( -1 == m_maxRotations )
           {
               m_maxRotations = Integer.MAX_VALUE;
           }
   
  -        if( m_rotation > m_maxRotations ) m_rotation = m_maxRotations;
  -        if( m_rotation < 0 ) m_rotation = 0;
  -    }
  +        if( -1 == initialRotation )
  +        {
  +            m_rotation = calculateInitialRotation();
  +        }
   
  -    public RevolvingFileStrategy( final File baseFile, final int maxRotations )
  -    {
  -        this( baseFile, -1, maxRotations );
  +        if( m_rotation > m_maxRotations )
  +        {
  +            m_rotation = m_maxRotations;
  +        }
  +        if( m_rotation < 0 )
  +        {
  +            m_rotation = 0;
  +        }
       }
   
       /**
  @@ -72,15 +79,165 @@
       public File nextFile()
       {
           final StringBuffer sb = new StringBuffer();
  -        final FieldPosition fp = new FieldPosition( NumberFormat.INTEGER_FIELD );
  +        final FieldPosition position =
  +            new FieldPosition( NumberFormat.INTEGER_FIELD );
           sb.append( m_baseFile );
   
  -        final StringBuffer result = m_decimalFormat.format( m_rotation, sb, fp );
  +        final StringBuffer result =
  +            m_decimalFormat.format( m_rotation, sb, position );
           m_rotation += 1;
   
  -        if( m_rotation >= m_maxRotations ) m_rotation = 0;
  +        if( m_rotation >= m_maxRotations )
  +        {
  +            m_rotation = 0;
  +        }
   
           return new File( result.toString() );
       }
  -}
   
  +    /**
  +     * Retrieve the current rotation number.
  +     *
  +     * @return the current rotation number.
  +     */
  +    public int getCurrentRotation()
  +    {
  +        return m_rotation;
  +    }
  +
  +    /**
  +     * Method that searches through files that
  +     * match the pattern for resolving file and determine
  +     * the last generation written to.
  +     *
  +     * @return the initial rotation
  +     */
  +    private int calculateInitialRotation()
  +    {
  +        final File[] matchingFiles = getMatchingFiles();
  +        if( null == matchingFiles || 0 == matchingFiles.length )
  +        {
  +            return 0;
  +        }
  +
  +        final int[] rotations = calculateRotations( matchingFiles );
  +
  +        //First we go through and look for maximumRotation
  +        int maxRotation = 0;
  +        for( int i = 0; i < rotations.length; i++ )
  +        {
  +            final int rotation = rotations[i ];
  +            if( rotation > maxRotation )
  +            {
  +                maxRotation = rotation;
  +            }
  +        }
  +
  +        //If the max rotation present on filessytem
  +        //is less than max rotation possible then return that
  +        //rotation
  +        if( m_maxRotations != maxRotation )
  +        {
  +            return maxRotation + 1;
  +        }
  +
  +        //Okay now we need to calculate the youngest file for our rotation
  +        long time = matchingFiles[ 0 ].lastModified();
  +
  +        //index of youngest file
  +        int youngest = 0;
  +        for( int i = 0; i < matchingFiles.length; i++ )
  +        {
  +            final File file = matchingFiles[ i ];
  +            final long lastModified = file.lastModified();
  +            System.out.println( "lastModified[" + rotations[ i ] + "] = " + lastModified
);
  +            if( lastModified > time )
  +            {
  +                time = lastModified;
  +                youngest = rotations[ i ] + 1;
  +            }
  +        }
  +
  +        return youngest;
  +    }
  +
  +    /**
  +     * Generate an array of rotation numbers for all the files specified.
  +     *
  +     * @param matchingFiles the files to generate rotation numbers for
  +     * @return the array containing rotations
  +     */
  +    private int[] calculateRotations( final File[] matchingFiles )
  +    {
  +        final int[] results = new int[ matchingFiles.length ];
  +
  +        for( int i = 0; i < matchingFiles.length; i++ )
  +        {
  +            final File file = matchingFiles[ i ];
  +
  +            // The files may be returned in any order
  +            //therefore calc the rotation number
  +            try
  +            {
  +                results[ i ] = calculateRotationForFile( file );
  +            }
  +            catch( final NumberFormatException nfe )
  +            {
  +                //If bad log file detected then set to -1
  +                results[ i ] = -1;
  +            }
  +        }
  +        return results;
  +    }
  +
  +    /**
  +     * Return the rotation for the specified file
  +     *
  +     * @param file the file to check
  +     * @return the rotation of the file
  +     */
  +    private int calculateRotationForFile( final File file )
  +    {
  +        final String filename = file.toString();
  +        final int length = filename.length();
  +        final int minDigits =
  +            m_decimalFormat.getMinimumIntegerDigits();
  +        final String rotation = filename.substring( length - minDigits );
  +
  +        return Integer.parseInt( rotation );
  +    }
  +
  +    /**
  +     * Get a list of files that could have been part of the rotation.
  +     *
  +     * @return the list of files that match
  +     */
  +    private File[] getMatchingFiles()
  +    {
  +        // First get the path of the base file. Note that this path includes
  +        // the path and the base of the file name itself.
  +        final String fullFilePathName = m_baseFile.getPath();
  +
  +        // Try to find the last path separator (if it exists)
  +        final int fileSeparatorPosition = fullFilePathName.lastIndexOf( File.separator
);
  +
  +        // If the last path separator does not exist the baseFile is a pure file name
  +        File basePath;
  +        String baseFileName;
  +        if( fileSeparatorPosition < 0 )
  +        {
  +            // assume the current directory
  +            basePath = new File( "." );
  +            baseFileName = fullFilePathName;
  +        }
  +        else
  +        {
  +            // Extract the sub-directory structure
  +            String m_parentPath = fullFilePathName.substring( 0, fileSeparatorPosition
);
  +            baseFileName = fullFilePathName.substring( fileSeparatorPosition + 1 );
  +            basePath = new File( m_parentPath );
  +        }
  +
  +        return basePath.listFiles( new BaseFileNameFilter( baseFileName ) );
  +    }
  +}
  
  
  
  1.1                  jakarta-avalon-logkit/src/java/org/apache/log/output/io/rotate/BaseFileNameFilter.java
  
  Index: BaseFileNameFilter.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.log.output.io.rotate;
  
  import java.io.FilenameFilter;
  import java.io.File;
  
  class BaseFileNameFilter
      implements FilenameFilter
  {
      private String m_baseFileName;
  
      BaseFileNameFilter( final String baseFileName )
      {
          m_baseFileName = baseFileName;
      }
  
      public boolean accept( File file, String name )
      {
          return ( name.startsWith( m_baseFileName ) );
      }
  }
  
  
  
  1.1                  jakarta-avalon-logkit/src/test/org/apache/log/output/test/RevolvingFileStrategyTestCase.java
  
  Index: RevolvingFileStrategyTestCase.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.log.output.test;
  
  import java.io.File;
  import java.io.IOException;
  import junit.framework.TestCase;
  import org.apache.log.output.io.rotate.RevolvingFileStrategy;
  
  /**
   * Test suite for the RevolvingFileStrategy.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   */
  public final class RevolvingFileStrategyTestCase
      extends TestCase
  {
      private static final int OLD_AGE = 100000000;
      private static final int YOUNG_AGE = -100000000;
  
      private final File m_baseFile;
      private final long m_now = System.currentTimeMillis();
  
      public RevolvingFileStrategyTestCase( final String name )
          throws IOException
      {
          super( name );
  
          m_baseFile = ( new File( "build/testdata/log" ) ).getCanonicalFile();
          m_baseFile.getParentFile().mkdirs();
      }
  
      private void deleteFiles( final int maxRotation )
          throws IOException
      {
          for( int i = 0; i <= maxRotation; i++ )
          {
              final File file = new File( getFilename( i ) );
              if( file.exists() && !file.delete() )
              {
                  throw new IOException( "Failed to delete file " + file );
              }
          }
      }
  
      private String getFilename( int i )
      {
          return m_baseFile.toString() + ".00000" + i;
      }
  
      private void createFile( final int rotation, final long age )
          throws IOException
      {
          final File file = new File( getFilename( rotation ) );
          if( !file.createNewFile() )
          {
              throw new IOException( "Failed to create file " + file );
          }
          final long time = m_now - age;
          file.setLastModified( time );
      }
  
      public void testNew()
          throws Exception
      {
          deleteFiles( 9 );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 0, strategy.getCurrentRotation() );
      }
  
      public void testRotationExisting()
          throws Exception
      {
          deleteFiles( 9 );
          createFile( 0, 0 );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 1, strategy.getCurrentRotation() );
      }
  
      public void testRotationExisting2()
          throws Exception
      {
          deleteFiles( 9 );
          createFile( 0, 0 );
          createFile( 1, 0 );
          createFile( 2, 0 );
          createFile( 3, 0 );
          createFile( 4, 0 );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 5, strategy.getCurrentRotation() );
      }
  
      public void testRotationExistingWithMissing()
          throws Exception
      {
          deleteFiles( 9 );
          createFile( 0, 0 );
          createFile( 4, 0 );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 5, strategy.getCurrentRotation() );
      }
  
      public void testRotationExistingWithOlderLower()
          throws Exception
      {
          deleteFiles( 9 );
          createFile( 0, OLD_AGE ); //Note this is oldest
          createFile( 4, 0 );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 5, strategy.getCurrentRotation() );
      }
  
      public void testRotationExistingWithOlderHigher()
          throws Exception
      {
          deleteFiles( 9 );
          createFile( 0, 0 );
          createFile( 4, OLD_AGE );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 5, strategy.getCurrentRotation() );
      }
  
      public void testFullRotation()
          throws Exception
      {
          deleteFiles( 9 );
          createFile( 0, 0 );
          createFile( 1, 0 );
          createFile( 2, 0 );
          createFile( 3, 0 );
          createFile( 4, 0 );
          createFile( 5, 0 );
          createFile( 6, 0 );
          createFile( 7, 0 );
          createFile( 8, 0 );
          createFile( 9, 0 );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 0, strategy.getCurrentRotation() );
      }
  
      public void testFullRotationWithYounger()
          throws Exception
      {
          deleteFiles( 9 );
          createFile( 0, 0 );
          createFile( 1, 0 );
          createFile( 2, 0 );
          createFile( 3, 0 );
          createFile( 4, 0 );
          createFile( 5, 0 );
          createFile( 6, 0 );
          createFile( 7, YOUNG_AGE );
          createFile( 8, 0 );
          createFile( 9, 0 );
  
          final RevolvingFileStrategy strategy =
              new RevolvingFileStrategy( m_baseFile, 9 );
  
          assertEquals( "rotation", 8, strategy.getCurrentRotation() );
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:avalon-cvs-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@jakarta.apache.org>


Mime
View raw message