Initial code

1.x 1.0.0
Julien Rosset 2 years ago
parent b384c11837
commit 157e0d8dd0

@ -1,3 +1,3 @@
# XXX
# PhpExtendedMonolog
XXX
Some extensions for [Monolog](https://github.com/Seldaek/monolog)

@ -1,21 +1,22 @@
{
"name": "jrosset/xxx",
"description": "XXX",
"name": "jrosset/extendedmonolog",
"description": "Some extensions for Monolog",
"keywords": [ ],
"minimum-stability": "stable",
"require": {
"php": "^7.4 || ^8.0"
"php": "^7.4 || ^8.0",
"jrosset/exceptionhelper": "^1.0",
"jrosset/lasterrorexception": "^1.0"
},
"autoload": {
"psr-4": {
"psr-4": {
"jrosset\\": "src/"
},
"exclude-from-classmap": [ "tests/" ]
}
},
"readme": "README.md",
"homepage": "https://git.jrosset.ovh/jrosset/XXX",
"homepage": "https://git.jrosset.ovh/jrosset/PhpExtendedMonolog",
"license": "CC-BY-4.0",
"authors": [
{
@ -25,9 +26,9 @@
],
"support": {
"email": "jul.rosset@gmail.com",
"issues": "https://git.jrosset.ovh/jrosset/XXX/issues",
"wiki": "https://git.jrosset.ovh/jrosset/XXX/wiki",
"docs": "https://git.jrosset.ovh/jrosset/XXX/wiki",
"source": "https://git.jrosset.ovh/jrosset/XXX"
"issues": "https://git.jrosset.ovh/jrosset/PhpExtendedMonolog/issues",
"wiki": "https://git.jrosset.ovh/jrosset/PhpExtendedMonolog/wiki",
"docs": "https://git.jrosset.ovh/jrosset/PhpExtendedMonolog/wiki",
"source": "https://git.jrosset.ovh/jrosset/PhpExtendedMonolog"
}
}
}

@ -0,0 +1,28 @@
<?php
namespace jrosset\ExtendedMonolog;
use jrosset\ExceptionHelper\ExceptionHelper;
use Monolog\Logger;
use Throwable;
/**
* A logger with method for managing exception directly
*/
class ExceptionLogger extends Logger implements ExceptionLoggerInterface {
/**
* @inheritDoc
*/
public function exception (int $level, Throwable $exception, array $context = []): void {
$this->addRecord(
$level,
ExceptionHelper::toString($exception, false),
array_merge(
[
'exception' => $exception,
],
$context
)
);
}
}

@ -0,0 +1,20 @@
<?php
namespace jrosset\ExtendedMonolog;
use Psr\Log\LoggerInterface;
use Throwable;
/**
* Describe a logger interface with method for managing exception directly
*/
interface ExceptionLoggerInterface extends LoggerInterface {
/**
* Adds a log record about an exception
*
* @param int $level The logging level (a Monolog or RFC 5424 level)
* @param Throwable $exception The exception
* @param array $context The log context
*/
public function exception (int $level, Throwable $exception, array $context = []): void;
}

@ -0,0 +1,79 @@
<?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());
}
}
}

@ -0,0 +1,30 @@
<?php
namespace jrosset\ExtendedMonolog;
use Monolog\Formatter\LineFormatter;
/**
* A formater for log files
*/
class LogFileFormatter extends LineFormatter {
/**
* @inheritDoc
*/
public function __construct () {
parent::__construct(
'[%datetime%] %level_name% : %message%' . PHP_EOL . '%context%' . PHP_EOL . '%extra%',
'H:i:s',
true,
true,
true
);
}
/**
* @inheritDoc
*/
public function format (array $record): string {
return preg_replace('/((?<!\\\\)\\\\[rn])+$/', PHP_EOL, parent::format($record));
}
}
Loading…
Cancel
Save