vendor/monolog/src/Monolog/Handler/RotatingFileHandler.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Monolog package.
       
     5  *
       
     6  * (c) Jordi Boggiano <j.boggiano@seld.be>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Monolog\Handler;
       
    13 
       
    14 use Monolog\Logger;
       
    15 
       
    16 /**
       
    17  * Stores logs to files that are rotated every day and a limited number of files are kept.
       
    18  *
       
    19  * This rotation is only intended to be used as a workaround. Using logrotate to
       
    20  * handle the rotation is strongly encouraged when you can use it.
       
    21  *
       
    22  * @author Christophe Coevoet <stof@notk.org>
       
    23  */
       
    24 class RotatingFileHandler extends StreamHandler
       
    25 {
       
    26     protected $filename;
       
    27     protected $maxFiles;
       
    28     protected $mustRotate;
       
    29 
       
    30     /**
       
    31      * @param string $filename
       
    32      * @param integer $maxFiles The maximal amount of files to keep (0 means unlimited)
       
    33      * @param integer $level The minimum logging level at which this handler will be triggered
       
    34      * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
       
    35      */
       
    36     public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true)
       
    37     {
       
    38         $this->filename = $filename;
       
    39         $this->maxFiles = (int) $maxFiles;
       
    40 
       
    41         $fileInfo = pathinfo($this->filename);
       
    42         $timedFilename = $fileInfo['dirname'].'/'.$fileInfo['filename'].'-'.date('Y-m-d');
       
    43         if (!empty($fileInfo['extension'])) {
       
    44             $timedFilename .= '.'.$fileInfo['extension'];
       
    45         }
       
    46 
       
    47         // disable rotation upfront if files are unlimited
       
    48         if (0 === $this->maxFiles) {
       
    49             $this->mustRotate = false;
       
    50         }
       
    51 
       
    52         parent::__construct($timedFilename, $level, $bubble);
       
    53     }
       
    54 
       
    55     /**
       
    56      * {@inheritdoc}
       
    57      */
       
    58     public function close()
       
    59     {
       
    60         parent::close();
       
    61 
       
    62         if (true === $this->mustRotate) {
       
    63             $this->rotate();
       
    64         }
       
    65     }
       
    66 
       
    67     /**
       
    68      * {@inheritdoc}
       
    69      */
       
    70     protected function write(array $record)
       
    71     {
       
    72         // on the first record written, if the log is new, we should rotate (once per day)
       
    73         if (null === $this->mustRotate) {
       
    74             $this->mustRotate = !file_exists($this->url);
       
    75         }
       
    76 
       
    77         parent::write($record);
       
    78     }
       
    79 
       
    80     /**
       
    81      * Rotates the files.
       
    82      */
       
    83     protected function rotate()
       
    84     {
       
    85         $fileInfo = pathinfo($this->filename);
       
    86         $glob = $fileInfo['dirname'].'/'.$fileInfo['filename'].'-*';
       
    87         if (!empty($fileInfo['extension'])) {
       
    88             $glob .= '.'.$fileInfo['extension'];
       
    89         }
       
    90         $iterator = new \GlobIterator($glob);
       
    91         $count = $iterator->count();
       
    92         if ($this->maxFiles >= $count) {
       
    93             // no files to remove
       
    94             return;
       
    95         }
       
    96 
       
    97         // Sorting the files by name to remove the older ones
       
    98         $array = iterator_to_array($iterator);
       
    99         usort($array, function($a, $b) {
       
   100             return strcmp($b->getFilename(), $a->getFilename());
       
   101         });
       
   102 
       
   103         foreach (array_slice($array, $this->maxFiles) as $file) {
       
   104             if ($file->isWritable()) {
       
   105                 unlink($file->getRealPath());
       
   106             }
       
   107         }
       
   108     }
       
   109 }