基于crontab的monolog文件轮转器

问题描述 投票:0回答:1

我们有 Monolog/RotatingFileHandler 和 cron 表达式。有人创建了一个理解 crontabs 表达式的 Monolog Filehandler 吗?我很想能够做到

$log = new Monolog\Logger( 'default' );
$log->pushHandler( new Monolog\Handler\CronRotateHandler( ROOT . 'log/default.log', "0 0 * * 6", Monolog\Logger::DEBUG ) );

创建每周六 00:00 轮换。这是已经创建的还是我应该自己编写一个?

cron monolog
1个回答
0
投票

基于dragonmantank/cron-expression 和 cesargb/php-log-rotation

<?php declare(strict_types=1);

namespace Monolog\Handler;

/*
 * This file is part of the Monolog package.
 *
 * (c) TheKing2 <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Monolog\Level;
use Monolog\Utils;

/**
 * Stores logs rotated by cron expression
 *
 * This rotation is only intended to be used as a workaround. Using logrotate to
 * handle the rotation is strongly encouraged when you can use it.
 *
 */
class CronRotatingFileHandler extends StreamHandler implements HandlerInterface
{
  private $filename;
  private $stateFilename;

  /**
   * @param int      $maxFiles       The maximal amount of files to keep (0 means unlimited)
   * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
   * @param bool     $useLocking     Try to lock log file before doing any writes
   */
  public function __construct(
    string $filename,
    array $rotateSettings,
    int|string|Level $level = Level::Debug,
    bool $bubble = false,
    ?int $filePermission = null,
    bool $useLocking = false
  ) {
    $this->filename = Utils::canonicalizePath( $filename );
    $this->checkRotate( $rotateSettings );

    parent::__construct( $this->filename, $level, $bubble, $filePermission, $useLocking );
  }
  /**
   * checkRotate
   *
   * @return void
   */
  protected function checkRotate( array $rotateSettings ): void
  {
    $cronExpression = $rotateSettings['cronExpression'] ?? '* * */1 * *';
    $maxFiles       = $rotateSettings['maxFiles'] ?? 366;
    $minSize        = $rotateSettings['minSize'] ?? 0;
    $compress       = $rotateSettings['compress'] ?? false;


    $stateFilename = Utils::canonicalizePath( $this->filename . '.state' );
    $fileInfo      = new \SplFileInfo( $stateFilename );
    if( !$fileInfo->isFile() ) {
      touch( $stateFilename );
    }
    // create state file if not exist
    $rotation = ( new \Cesargb\Log\Rotation() )
      ->files( $maxFiles )
      ->minSize( $minSize );
    if( $compress ) {
      $rotation->compress();
    }
    $cron = new \Cron\CronExpression( $cronExpression );
    // check if log file is due based on state file modified time
    $dateTime     = new \DateTimeImmutable();                         // current datetime
    $filedateTime = $dateTime->setTimeStamp( $fileInfo->getMTime() ); // state-file datetime
    $nextRun      = $cron->getNextRunDate( $filedateTime );           // next-run datetime

    // if log file is due, rotate it
    if( $nextRun < $dateTime ) {
      // rotate log file
      touch( $fileInfo->getRealPath() );
      $rotation->rotate( $this->filename );

    }

  }
}

© www.soinside.com 2019 - 2024. All rights reserved.