Subversion Repositories phpLibraryV2

Rev

Rev 4 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

<?php

   class Logging {
      public $logFileName;
      public $maxLogSize;
      public $truncateLogByPercent;
      
      public function __construct( $logFileName = '', $maxLogSize = 0, $truncateLogByPercent = '0.1' ) {
         $this->logFileName = $logFileName;
         $this->maxLogSize = $maxLogSize;
         $this->truncateLogByPercent = $truncateLogByPercent;
      } // function __construct
      
      public function log( $string ) {
         if ( $logFileName ) {
            $fh = fopen( $this->logFileName, 'a');
            fwrite($fh, date('Y-m-d H:i:s') . "\t$string\n" );
            fclose($fh);
         }
         if ($this->maxLogSize) { // it is defined, so we must check on the size
            if (sprintf("%u", filesize($this->logFileName)) >= $this->maxLogSize ) // file is too big, remove top $truncateLogByPercent percent
               $this->truncateLog();
         }
      } // function log
      
   /* 
      Note: this is an initial attempt to build this function.
      First, it is not horribly critical if we don't truncate right at $maxLogSize, so if we don't get a lock, we just blow it off
      Second, we need to remove the first 10% (or whatever) of the file, so we can't use built in's like truncate or anything
      What I do here is read the first 10% (or whatever $truncateLogByPercent is), then do a gets (to get to the end of that line)
      Then, create a temporary file, dump the rest of the log file into it.
      Then, truncate the log file to 0, and dump the temp file back into it.
      
      I'm sure there is a much, much better way of doing this, and I would think that having two file handles on the same file would
      do it, but I'm scared of what other file systems would do, so I'll do it this way.
      
      NOTE: file_get_contents and file_put_contents would be more efficient, but I can't lock the file that way.
   */
   private function truncateLog() {
      $fh = fopen( $this->logFileName, 'w');
      if ( flock( $fh, LOCK_EX  | LOCK_NB ) ) { // try to get a lock, but don't be too concerned if we can't right now. We can always try next time
         // got the lock, truncate the file from the top :(
         fseek( $fh, $this->maxLogSize * $this->truncateLogByPercent ); // go past the first truncateLogByPercent percent of file
         fgets( $fh ); // go to the end of the line (text only)
         $tmpfh = tmpfile(); // create a temporary file
         while ( fwrite($tmpfh, fread($fh, 1024) ) ) {} // copy the rest of the file to a temp file
         fseek( $fh, 0 );  // move back to the beginning of the log file
         ftruncate( $fh, 0 ); // and empty it
         fseek( $tmpfh, 0); // and the temp file
         while ( fwrite($fh, fread($tmpfh, 1024) ) ) {} // copy the rest of the file to a temp file
         fclose ($fh); // unlocks it at the same time
         fclose ($tmpfh); // removes it from disk also
      }
   }
   
   } // class Logging

?>