You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PhpExtendedMonolog/src/ExtendedMonolog/LogDirectoryHandler.php

79 lines
2.6 KiB
PHP

<?php
namespace jrosset\ExtendedMonolog;
use DateInterval;
use DateTimeImmutable;
use DirectoryIterator;
use jrosset\LastErrorException\LastErrorException;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use RuntimeException;
use Throwable;
/**
* A handler for storing log in a directory: one file per day, with an auto-clean mechanism
*
* The default formatter is {@see LogFileFormatter}
*/
class LogDirectoryHandler extends StreamHandler {
/**
* Initialization
*
* @param string $dirPath The log directory path
* @param int $historyNumberOfDays The maximum number of history files to keep (in number of days)
*
* @throws Throwable If an error occurs
*/
public function __construct (string $dirPath, int $historyNumberOfDays = 30) {
$dirPath = realpath($dirPath) . DIRECTORY_SEPARATOR;
$this->normalizeDirectory($dirPath, $historyNumberOfDays);
parent::__construct(
$dirPath . date('Y-m-d') . '.log',
Logger::WARNING
);
$this->setFormatter(new LogFileFormatter());
}
/**
* Normalize a directory: create if missing and clear old files
*
* @param string $dirPath The directory path
* @param int $historyNumberOfDays The maximum number of history files to keep (in number of days)
*
* @return void
*
* @throws Throwable If an error occurs
*/
private function normalizeDirectory (string $dirPath, int $historyNumberOfDays = 30): void {
if (!file_exists($dirPath) || !is_dir($dirPath)) {
error_clear_last();
if (!mkdir($dirPath, 0755, true)) {
throw new RuntimeException('Failed to create log directory: ' . $dirPath, 0, LastErrorException::createFromLastError());
}
}
$dateLimit = (new DateTimeImmutable('now'))->sub(new DateInterval('P' . $historyNumberOfDays . 'D'));
$iterator = new DirectoryIterator($dirPath);
foreach ($iterator as $fileInfo) {
if ($fileInfo->isDot() || mb_substr($fileInfo->getFilename(), 0, 1) === '.') {
continue;
}
if (!$fileInfo->isFile()) {
continue;
}
if (preg_match('/^(?<date>\\d{4}-\\d{2}-\\d{2})(?:[_-].*)?\.log$/i', $fileInfo->getFilename(), $match) !== 1) {
continue;
}
$date = DateTimeImmutable::createFromFormat('Y-m-d', $match['date']);
if ($date >= $dateLimit) {
continue;
}
unlink($fileInfo->getPathname());
}
}
}