Skip navigation
4584 Views 7 Replies Latest reply: Dec 2, 2008 9:57 AM by chris_s RSS
Bronze 7 posts since
Apr 26, 2007
Currently Being Moderated

Aug 28, 2007 9:24 AM

Gaps in message audit logs

We have a large gaps in openfire audit logs. These gaps occur at log file rotation points.

 

For example, the last entry in jive.audit-20070825-001.log is time stamped Aug 24, 2007 11:43:03:697 PM

 

And the first entry in jive.audit-20070825-002.log is time stamped: Aug 25, 2007 06:55:38:091 PM

 

So, most logs for 08/25 are missing.

 

It appears that we have this type of problem pretty frequently (once in day or two days). (Yes, the server is running and functioning during that time. It's 3.3.2 on linux).

 

Has anyone seen this or can shed some light on this? Is setting "Maximum size of all files" in message audit policy can have such effect?

 

Thanks in advance.

  • LG KeyContributor 5,935 posts since
    Dec 13, 2005
    Currently Being Moderated
    Aug 28, 2007 12:36 PM (in response to dmitryd)
    Re: Gaps in message audit logs

    Hi,

     

    did you set the max. size to more than 2 GB?

    JM-909 is the known problem about larger sizes.

     

    LG

      • chris_s Bronze 5 posts since
        Jul 5, 2007
        Currently Being Moderated
        Dec 11, 2007 4:23 AM (in response to dmitryd)
        Re: Gaps in message audit logs

        We had the same problem.  The issue is down to the way log-rollover works. It is consistently overwriting old log files hence there are gaps in the data.  

         

        The code lists the log files to find the most recent.   It assumes that the most recent log file  is at the end of the list.  This isn't guarenteed to be true.   It seems to work fine on Windows but consistently fails on Linux.

         

        In more detail:  The file: org.jivesoftware.openfire.audit.spi.AuditorImpl.java, line 276 does this:

        File[] files = baseFolder.listFiles(filter);
        

         

        Then line 283 does this to determine the most recent file and hence work out the next log file number to use.

        File lastFile = files[http://files.length - 1|http://files.length - 1];
        

         

        However, the javadoc for  File.listFiles() states

         

        "There is no guarantee that the name strings in the resulting array will appear in any specific order; they are not, in particular, guaranteed to appear in alphabetical order."

        So, on Linux the code retrieves a log file that is not the latest (say 001.log), increments the log number (to say 002) and thus overwrites 002.log with newer data.  This gives you the gaps you see.

         

        The simplest fix is to add the following code before line 283:

        // File implements Comparable as a lexographical ordering of abstract
        // path names.  Arrays.sort() uses the Comparable interface.  So this shoul
        // give us an alpha sorted array of files.  This is ok, because the fil
        // name format is such that an alpha sort will produce a date sort + log+
        // number sort. We want a date + log number sort so that the next line of++
        // code after this one retrieves the most last log file in the sequence
        // Without this fix, on Linux, the list of log files is not guarentee
        // to be in the correct order 
        Arrays.sort(files); 
        

         

         

        A more robust solution might be to write code that explicitly finds the largest log file number rather than relying on an alpha sort.  Or, remove the rollover code entirely and just use log4j instead - although AFAIK this doesn't support Openfire's exact log rollover policy. 

         

        Looking at the rest of the code base, there doesn't seem to be any other similar mis-use of File.listFiles() although the class-loaders (JiveClassLoader and PluginClassLoader) use it which might cause different versions of the same class to be loaded on different platforms.

         

        Code to demonstrate the problem:

         

        
        import java.io.File;
        import java.io.FilenameFilter;
        import java.util.Arrays;
         
        public class FileListTest
        {
           // arg0 is log directory, arg1 is a date e.g. 20071206
           public static void main( String[] args )
           {
              File baseFolder = new File( args[0] );
              final String filePrefix = "jive.audit-" + args[1];
         
              // orig code
              FilenameFilter filter = new FilenameFilter( )
              {
                 public boolean accept( File dir, String name )
                 {
                    return name.startsWith( filePrefix ) && name.endsWith( ".log" );
                 }
              };
              File[] files = baseFolder.listFiles( filter );
              // orig code end
         
              // Take a copy of the file list for later comparison
              File[] unsortedList = new File[http://files.length|http://files.length];
              System.arraycopy( files, 0, unsortedList, 0, files.length );
         
              Arrays.sort( files ); // Fix code
         
              // Print unsorted vs sorted. Note differences with an arrow.
              for ( int i = 0; i < unsortedList.length; i++ )
              {
                 System.out.print( unsortedList[i] + "  " + files[i] );
                 if ( !unsortedList[i].equals( files[i] ) )
                 {
                    System.out.print( " <-----" );
                 }
                 System.out.print( "\n" );
              }
           }
        }
        

         

         

        Example usage:

        java FileListTest /opt/openfire/logs 20071205

        /opt/openfire/logs/jive.audit-20071205-000.log  /opt/openfire/logs/jive.audit-20071205-000.log

        /opt/openfire/logs/jive.audit-20071205-001.log  /opt/openfire/logs/jive.audit-20071205-001.log

        /opt/openfire/logs/jive.audit-20071205-003.log  /opt/openfire/logs/jive.audit-20071205-002.log &lt;-----

        /opt/openfire/logs/jive.audit-20071205-002.log  /opt/openfire/logs/jive.audit-20071205-003.log &lt;-----

        LHS show the default list order returned from listFiles(), RHS shows it sorted. Lines marked with an arrow show differences which would result in log file gaps

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points