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.
79 lines
2.6 KiB
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());
|
|
}
|
|
}
|
|
} |