Contributors: Sergio Strampelli.

* * An example: * * {@example ../../examples/php/appender_socket.php 19} * * {@example ../../examples/resources/appender_socket.properties 18} * * @version $Revision$ * @package log4php * @subpackage appenders */ class LoggerAppenderRollingFile extends LoggerAppenderFile { /** * Set the maximum size that the output file is allowed to reach * before being rolled over to backup files. * *

In configuration files, the MaxFileSize option takes a * long integer in the range 0 - 2^63. You can specify the value * with the suffixes "KB", "MB" or "GB" so that the integer is * interpreted being expressed respectively in kilobytes, megabytes * or gigabytes. For example, the value "10KB" will be interpreted * as 10240.

*

The default maximum file size is 10MB.

* *

Note that MaxFileSize cannot exceed 2 GB.

* * @var integer */ private $maxFileSize = 10485760; /** * Set the maximum number of backup files to keep around. * *

The MaxBackupIndex option determines how many backup * files are kept before the oldest is erased. This option takes * a positive integer value. If set to zero, then there will be no * backup files and the log file will be truncated when it reaches * MaxFileSize.

*

There is one backup file by default.

* * @var integer */ private $maxBackupIndex = 1; /** * @var string the filename expanded */ private $expandedFileName = null; public function __destruct() { parent::__destruct(); } /** * Returns the value of the MaxBackupIndex option. * @return integer */ private function getExpandedFileName() { return $this->expandedFileName; } /** * Get the maximum size that the output file is allowed to reach * before being rolled over to backup files. * @return integer */ public function getMaximumFileSize() { return $this->maxFileSize; } /** * Implements the usual roll over behaviour. * *

If MaxBackupIndex is positive, then files File.1, ..., File.MaxBackupIndex -1 are renamed to File.2, ..., File.MaxBackupIndex. * Moreover, File is renamed File.1 and closed. A new File is created to receive further log output. * *

If MaxBackupIndex is equal to zero, then the File is truncated with no backup files created. * * Rollover must be called while the file is locked so that it is safe for concurrent access. */ private function rollOver() { // If maxBackups <= 0, then there is no file renaming to be done. if($this->maxBackupIndex > 0) { $fileName = $this->getExpandedFileName(); // Delete the oldest file, to keep Windows happy. $file = $fileName . '.' . $this->maxBackupIndex; if(is_writable($file)) unlink($file); // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2} for($i = $this->maxBackupIndex - 1; $i >= 1; $i--) { $file = $fileName . "." . $i; if(is_readable($file)) { $target = $fileName . '.' . ($i + 1); rename($file, $target); } } // Backup the active file copy($fileName, "$fileName.1"); } // Truncate the active file ftruncate($this->fp, 0); rewind($this->fp); } public function setFile($fileName) { $this->file = $fileName; // As LoggerAppenderFile does not create the directory, it has to exist. // realpath() fails if the argument does not exist so the filename is separated. $this->expandedFileName = realpath(dirname($fileName)); if ($this->expandedFileName === false) throw new Exception("Directory of $fileName does not exist!"); $this->expandedFileName .= DIRECTORY_SEPARATOR . basename($fileName); } /** * Set the maximum number of backup files to keep around. * *

The MaxBackupIndex option determines how many backup * files are kept before the oldest is erased. This option takes * a positive integer value. If set to zero, then there will be no * backup files and the log file will be truncated when it reaches * MaxFileSize. * * @param mixed $maxBackups */ public function setMaxBackupIndex($maxBackups) { if(is_numeric($maxBackups)) { $this->maxBackupIndex = abs((int)$maxBackups); } } /** * Set the maximum size that the output file is allowed to reach * before being rolled over to backup files. * * @param mixed $maxFileSize * @see setMaxFileSize() * @deprecated */ public function setMaximumFileSize($maxFileSize) { return $this->setMaxFileSize($maxFileSize); } /** * Set the maximum size that the output file is allowed to reach * before being rolled over to backup files. *

In configuration files, the maxFileSize option takes an * long integer in the range 0 - 2^63. You can specify the value * with the suffixes "KB", "MB" or "GB" so that the integer is * interpreted being expressed respectively in kilobytes, megabytes * or gigabytes. For example, the value "10KB" will be interpreted * as 10240. * * @param mixed $value * @return the actual file size set */ public function setMaxFileSize($value) { $maxFileSize = null; $numpart = substr($value,0, strlen($value) -2); $suffix = strtoupper(substr($value, -2)); switch($suffix) { case 'KB': $maxFileSize = (int)((int)$numpart * 1024); break; case 'MB': $maxFileSize = (int)((int)$numpart * 1024 * 1024); break; case 'GB': $maxFileSize = (int)((int)$numpart * 1024 * 1024 * 1024); break; default: if(is_numeric($value)) { $maxFileSize = (int)$value; } } if($maxFileSize !== null) { $this->maxFileSize = abs($maxFileSize); } return $this->maxFileSize; } public function append(LoggerLoggingEvent $event) { if($this->fp and $this->layout !== null) { if(flock($this->fp, LOCK_EX)) { fwrite($this->fp, $this->layout->format($event)); // Stats cache must be cleared, otherwise filesize() returns cached results clearstatcache(); // Rollover if needed if (filesize($this->expandedFileName) > $this->maxFileSize) { $this->rollOver(); } flock($this->fp, LOCK_UN); } else { $this->closed = true; } } } /** * @return Returns the maximum number of backup files to keep around. */ public function getMaxBackupIndex() { return $this->maxBackupIndex; } /** * @return Returns the maximum size that the output file is allowed to reach * before being rolled over to backup files. */ public function getMaxFileSize() { return $this->maxFileSize; } }