update
This commit is contained in:
104
projects/priceservice/vendor/symfony/monolog-bridge/CHANGELOG.md
vendored
Normal file
104
projects/priceservice/vendor/symfony/monolog-bridge/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
6.4
|
||||
---
|
||||
|
||||
* Add native return type to `Logger::clear()` and to `DebugProcessor::clear()`
|
||||
* Deprecate class `Logger`, use HttpKernel's `DebugLoggerConfigurator` instead
|
||||
|
||||
6.1
|
||||
---
|
||||
|
||||
* Add support for Monolog 3
|
||||
|
||||
6.0
|
||||
---
|
||||
|
||||
* The `$actionLevel` constructor argument of `NotFoundActivationStrategy` has been replaced by the `$inner` one which expects an `ActivationStrategyInterface` to decorate instead
|
||||
* The `$actionLevel` constructor argument of `HttpCodeActivationStrategy` has been replaced by the `$inner` one which expects an `ActivationStrategyInterface` to decorate instead
|
||||
* Remove `ResetLoggersWorkerSubscriber` in favor of "reset_on_message" option in messenger configuration
|
||||
* Remove `SwiftMailerHandler`, use `MailerHandler` instead
|
||||
|
||||
5.4
|
||||
---
|
||||
|
||||
* Deprecate `ResetLoggersWorkerSubscriber` to reset buffered logs in messenger
|
||||
workers, use "reset_on_message" option in messenger configuration instead.
|
||||
|
||||
5.3
|
||||
---
|
||||
|
||||
* Add `ResetLoggersWorkerSubscriber` to reset buffered logs in messenger workers
|
||||
|
||||
5.2.0
|
||||
-----
|
||||
|
||||
* The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` has been deprecated and replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\NotFoundActivationStrategy` will become final in 6.0.
|
||||
* The `$actionLevel` constructor argument of `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` has been deprecated and replaced by the `$inner` one which expects an ActivationStrategyInterface to decorate instead. `Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy` will become final in 6.0
|
||||
|
||||
5.1.0
|
||||
-----
|
||||
|
||||
* Added `MailerHandler`
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
||||
* The methods `DebugProcessor::getLogs()`, `DebugProcessor::countErrors()`, `Logger::getLogs()` and `Logger::countErrors()` have a new `$request` argument.
|
||||
* Added support for Monolog 2.
|
||||
|
||||
4.4.0
|
||||
-----
|
||||
|
||||
* The `RouteProcessor` class has been made final
|
||||
* Added `ElasticsearchLogstashHandler`
|
||||
* Added the `ServerLogCommand`. Backport from the deprecated WebServerBundle
|
||||
|
||||
4.3.0
|
||||
-----
|
||||
|
||||
* added `ConsoleCommandProcessor`: monolog processor that adds command name and arguments
|
||||
* added `RouteProcessor`: monolog processor that adds route name, controller::action and route params
|
||||
|
||||
4.2.0
|
||||
-----
|
||||
|
||||
* The methods `DebugProcessor::getLogs()`, `DebugProcessor::countErrors()`, `Logger::getLogs()`
|
||||
and `Logger::countErrors()` will have a new `$request` argument in version 5.0, not defining
|
||||
it is deprecated
|
||||
|
||||
4.1.0
|
||||
-----
|
||||
|
||||
* `WebProcessor` now implements `EventSubscriberInterface` in order to be easily autoconfigured
|
||||
|
||||
4.0.0
|
||||
-----
|
||||
|
||||
* the `$format`, `$dateFormat`, `$allowInlineLineBreaks`, and `$ignoreEmptyContextAndExtra`
|
||||
constructor arguments of the `ConsoleFormatter` class have been removed, use
|
||||
`$options` instead
|
||||
* the `DebugHandler` class has been removed
|
||||
|
||||
3.3.0
|
||||
-----
|
||||
|
||||
* Improved the console handler output formatting by adding var-dumper support
|
||||
|
||||
3.0.0
|
||||
-----
|
||||
|
||||
* deprecated interface `Symfony\Component\HttpKernel\Log\LoggerInterface` has been removed
|
||||
* deprecated methods `Logger::crit()`, `Logger::emerg()`, `Logger::err()` and `Logger::warn()` have been removed
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
||||
* added ConsoleHandler and ConsoleFormatter which can be used to show log messages
|
||||
in the console output depending on the verbosity settings
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
* added ChromePhpHandler
|
||||
174
projects/priceservice/vendor/symfony/monolog-bridge/Command/ServerLogCommand.php
vendored
Normal file
174
projects/priceservice/vendor/symfony/monolog-bridge/Command/ServerLogCommand.php
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Command;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Handler\HandlerInterface;
|
||||
use Monolog\Level;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter;
|
||||
use Symfony\Bridge\Monolog\Handler\ConsoleHandler;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Exception\LogicException;
|
||||
use Symfony\Component\Console\Exception\RuntimeException;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
||||
|
||||
/**
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
*/
|
||||
#[AsCommand(name: 'server:log', description: 'Start a log server that displays logs in real time')]
|
||||
class ServerLogCommand extends Command
|
||||
{
|
||||
private const BG_COLOR = ['black', 'blue', 'cyan', 'green', 'magenta', 'red', 'white', 'yellow'];
|
||||
|
||||
private ExpressionLanguage $el;
|
||||
private HandlerInterface $handler;
|
||||
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
if (!class_exists(ConsoleFormatter::class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// based on a symfony/symfony package, it crashes due a missing FormatterInterface from monolog/monolog
|
||||
if (!interface_exists(FormatterInterface::class)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return parent::isEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
if (!class_exists(ConsoleFormatter::class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this
|
||||
->addOption('host', null, InputOption::VALUE_REQUIRED, 'The server host', '0.0.0.0:9911')
|
||||
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The line format', ConsoleFormatter::SIMPLE_FORMAT)
|
||||
->addOption('date-format', null, InputOption::VALUE_REQUIRED, 'The date format', ConsoleFormatter::SIMPLE_DATE)
|
||||
->addOption('filter', null, InputOption::VALUE_REQUIRED, 'An expression to filter log. Example: "level > 200 or channel in [\'app\', \'doctrine\']"')
|
||||
->setHelp(<<<'EOF'
|
||||
<info>%command.name%</info> starts a log server to display in real time the log
|
||||
messages generated by your application:
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
|
||||
To filter the log messages using any ExpressionLanguage compatible expression, use the <comment>--filter</> option:
|
||||
|
||||
<info>php %command.full_name% --filter="level > 200 or channel in ['app', 'doctrine']"</info>
|
||||
EOF
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$filter = $input->getOption('filter');
|
||||
if ($filter) {
|
||||
if (!class_exists(ExpressionLanguage::class)) {
|
||||
throw new LogicException('Package "symfony/expression-language" is required to use the "filter" option. Try running "composer require symfony/expression-language".');
|
||||
}
|
||||
$this->el = new ExpressionLanguage();
|
||||
}
|
||||
|
||||
$this->handler = new ConsoleHandler($output, true, [
|
||||
OutputInterface::VERBOSITY_NORMAL => Logger::DEBUG,
|
||||
]);
|
||||
|
||||
$this->handler->setFormatter(new ConsoleFormatter([
|
||||
'format' => str_replace('\n', "\n", $input->getOption('format')),
|
||||
'date_format' => $input->getOption('date-format'),
|
||||
'colors' => $output->isDecorated(),
|
||||
'multiline' => OutputInterface::VERBOSITY_DEBUG <= $output->getVerbosity(),
|
||||
]));
|
||||
|
||||
if (!str_contains($host = $input->getOption('host'), '://')) {
|
||||
$host = 'tcp://'.$host;
|
||||
}
|
||||
|
||||
if (!$socket = stream_socket_server($host, $errno, $errstr)) {
|
||||
throw new RuntimeException(sprintf('Server start failed on "%s": ', $host).$errstr.' '.$errno);
|
||||
}
|
||||
|
||||
foreach ($this->getLogs($socket) as $clientId => $message) {
|
||||
$record = unserialize(base64_decode($message));
|
||||
|
||||
// Impossible to decode the message, give up.
|
||||
if (false === $record) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($filter && !$this->el->evaluate($filter, $record)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->displayLog($output, $clientId, $record);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function getLogs($socket): iterable
|
||||
{
|
||||
$sockets = [(int) $socket => $socket];
|
||||
$write = [];
|
||||
|
||||
while (true) {
|
||||
$read = $sockets;
|
||||
stream_select($read, $write, $write, null);
|
||||
|
||||
foreach ($read as $stream) {
|
||||
if ($socket === $stream) {
|
||||
$stream = stream_socket_accept($socket);
|
||||
$sockets[(int) $stream] = $stream;
|
||||
} elseif (feof($stream)) {
|
||||
unset($sockets[(int) $stream]);
|
||||
fclose($stream);
|
||||
} else {
|
||||
yield (int) $stream => fgets($stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function displayLog(OutputInterface $output, int $clientId, array $record): void
|
||||
{
|
||||
if (isset($record['log_id'])) {
|
||||
$clientId = unpack('H*', $record['log_id'])[1];
|
||||
}
|
||||
$logBlock = sprintf('<bg=%s> </>', self::BG_COLOR[$clientId % 8]);
|
||||
$output->write($logBlock);
|
||||
|
||||
if (Logger::API >= 3) {
|
||||
$record = new LogRecord(
|
||||
$record['datetime'],
|
||||
$record['channel'],
|
||||
Level::fromValue($record['level']),
|
||||
$record['message'],
|
||||
$record['context']->getValue(true),
|
||||
$record['extra']->getValue(true),
|
||||
);
|
||||
}
|
||||
|
||||
$this->handler->handle($record);
|
||||
}
|
||||
}
|
||||
51
projects/priceservice/vendor/symfony/monolog-bridge/Formatter/CompatibilityFormatter.php
vendored
Normal file
51
projects/priceservice/vendor/symfony/monolog-bridge/Formatter/CompatibilityFormatter.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Formatter;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
|
||||
if (Logger::API >= 3) {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityFormatter
|
||||
{
|
||||
abstract private function doFormat(array|LogRecord $record): mixed;
|
||||
|
||||
public function format(LogRecord $record): mixed
|
||||
{
|
||||
return $this->doFormat($record);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityFormatter
|
||||
{
|
||||
abstract private function doFormat(array|LogRecord $record): mixed;
|
||||
|
||||
public function format(array $record): mixed
|
||||
{
|
||||
return $this->doFormat($record);
|
||||
}
|
||||
}
|
||||
}
|
||||
212
projects/priceservice/vendor/symfony/monolog-bridge/Formatter/ConsoleFormatter.php
vendored
Normal file
212
projects/priceservice/vendor/symfony/monolog-bridge/Formatter/ConsoleFormatter.php
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Formatter;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||
use Symfony\Component\VarDumper\Cloner\Data;
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
|
||||
/**
|
||||
* Formats incoming records for console output by coloring them depending on log level.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class ConsoleFormatter implements FormatterInterface
|
||||
{
|
||||
use CompatibilityFormatter;
|
||||
|
||||
public const SIMPLE_FORMAT = "%datetime% %start_tag%%level_name%%end_tag% <comment>[%channel%]</> %message%%context%%extra%\n";
|
||||
public const SIMPLE_DATE = 'H:i:s';
|
||||
|
||||
private const LEVEL_COLOR_MAP = [
|
||||
Logger::DEBUG => 'fg=white',
|
||||
Logger::INFO => 'fg=green',
|
||||
Logger::NOTICE => 'fg=blue',
|
||||
Logger::WARNING => 'fg=cyan',
|
||||
Logger::ERROR => 'fg=yellow',
|
||||
Logger::CRITICAL => 'fg=red',
|
||||
Logger::ALERT => 'fg=red',
|
||||
Logger::EMERGENCY => 'fg=white;bg=red',
|
||||
];
|
||||
|
||||
private array $options;
|
||||
private VarCloner $cloner;
|
||||
|
||||
/**
|
||||
* @var resource|null
|
||||
*/
|
||||
private $outputBuffer;
|
||||
|
||||
private CliDumper $dumper;
|
||||
|
||||
/**
|
||||
* Available options:
|
||||
* * format: The format of the outputted log string. The following placeholders are supported: %datetime%, %start_tag%, %level_name%, %end_tag%, %channel%, %message%, %context%, %extra%;
|
||||
* * date_format: The format of the outputted date string;
|
||||
* * colors: If true, the log string contains ANSI code to add color;
|
||||
* * multiline: If false, "context" and "extra" are dumped on one line.
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->options = array_replace([
|
||||
'format' => self::SIMPLE_FORMAT,
|
||||
'date_format' => self::SIMPLE_DATE,
|
||||
'colors' => true,
|
||||
'multiline' => false,
|
||||
'level_name_format' => '%-9s',
|
||||
'ignore_empty_context_and_extra' => true,
|
||||
], $options);
|
||||
|
||||
if (class_exists(VarCloner::class)) {
|
||||
$this->cloner = new VarCloner();
|
||||
$this->cloner->addCasters([
|
||||
'*' => $this->castObject(...),
|
||||
]);
|
||||
|
||||
$this->outputBuffer = fopen('php://memory', 'r+');
|
||||
if ($this->options['multiline']) {
|
||||
$output = $this->outputBuffer;
|
||||
} else {
|
||||
$output = $this->echoLine(...);
|
||||
}
|
||||
|
||||
$this->dumper = new CliDumper($output, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
public function formatBatch(array $records): mixed
|
||||
{
|
||||
foreach ($records as $key => $record) {
|
||||
$records[$key] = $this->format($record);
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
private function doFormat(array|LogRecord $record): mixed
|
||||
{
|
||||
if ($record instanceof LogRecord) {
|
||||
$record = $record->toArray();
|
||||
}
|
||||
$record = $this->replacePlaceHolder($record);
|
||||
|
||||
if (!$this->options['ignore_empty_context_and_extra'] || !empty($record['context'])) {
|
||||
$context = ($this->options['multiline'] ? "\n" : ' ').$this->dumpData($record['context']);
|
||||
} else {
|
||||
$context = '';
|
||||
}
|
||||
|
||||
if (!$this->options['ignore_empty_context_and_extra'] || !empty($record['extra'])) {
|
||||
$extra = ($this->options['multiline'] ? "\n" : ' ').$this->dumpData($record['extra']);
|
||||
} else {
|
||||
$extra = '';
|
||||
}
|
||||
|
||||
$formatted = strtr($this->options['format'], [
|
||||
'%datetime%' => $record['datetime'] instanceof \DateTimeInterface
|
||||
? $record['datetime']->format($this->options['date_format'])
|
||||
: $record['datetime'],
|
||||
'%start_tag%' => sprintf('<%s>', self::LEVEL_COLOR_MAP[$record['level']]),
|
||||
'%level_name%' => sprintf($this->options['level_name_format'], $record['level_name']),
|
||||
'%end_tag%' => '</>',
|
||||
'%channel%' => $record['channel'],
|
||||
'%message%' => $this->replacePlaceHolder($record)['message'],
|
||||
'%context%' => $context,
|
||||
'%extra%' => $extra,
|
||||
]);
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function echoLine(string $line, int $depth, string $indentPad): void
|
||||
{
|
||||
if (-1 !== $depth) {
|
||||
fwrite($this->outputBuffer, $line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function castObject(mixed $v, array $a, Stub $s, bool $isNested): array
|
||||
{
|
||||
if ($this->options['multiline']) {
|
||||
return $a;
|
||||
}
|
||||
|
||||
if ($isNested && !$v instanceof \DateTimeInterface) {
|
||||
$s->cut = -1;
|
||||
$a = [];
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
private function replacePlaceHolder(array $record): array
|
||||
{
|
||||
$message = $record['message'];
|
||||
|
||||
if (!str_contains($message, '{')) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
$context = $record['context'];
|
||||
|
||||
$replacements = [];
|
||||
foreach ($context as $k => $v) {
|
||||
// Remove quotes added by the dumper around string.
|
||||
$v = trim($this->dumpData($v, false), '"');
|
||||
$v = OutputFormatter::escape($v);
|
||||
$replacements['{'.$k.'}'] = sprintf('<comment>%s</>', $v);
|
||||
}
|
||||
|
||||
$record['message'] = strtr($message, $replacements);
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
private function dumpData(mixed $data, ?bool $colors = null): string
|
||||
{
|
||||
if (!isset($this->dumper)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (null === $colors) {
|
||||
$this->dumper->setColors($this->options['colors']);
|
||||
} else {
|
||||
$this->dumper->setColors($colors);
|
||||
}
|
||||
|
||||
if (!$data instanceof Data) {
|
||||
$data = $this->cloner->cloneVar($data);
|
||||
}
|
||||
$data = $data->withRefHandles(false);
|
||||
$this->dumper->dump($data);
|
||||
|
||||
$dump = stream_get_contents($this->outputBuffer, -1, 0);
|
||||
rewind($this->outputBuffer);
|
||||
ftruncate($this->outputBuffer, 0);
|
||||
|
||||
return rtrim($dump);
|
||||
}
|
||||
}
|
||||
54
projects/priceservice/vendor/symfony/monolog-bridge/Formatter/VarDumperFormatter.php
vendored
Normal file
54
projects/priceservice/vendor/symfony/monolog-bridge/Formatter/VarDumperFormatter.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Formatter;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\VarDumper\Cloner\VarCloner;
|
||||
|
||||
/**
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class VarDumperFormatter implements FormatterInterface
|
||||
{
|
||||
use CompatibilityFormatter;
|
||||
|
||||
private VarCloner $cloner;
|
||||
|
||||
public function __construct(?VarCloner $cloner = null)
|
||||
{
|
||||
$this->cloner = $cloner ?? new VarCloner();
|
||||
}
|
||||
|
||||
private function doFormat(array|LogRecord $record): mixed
|
||||
{
|
||||
if ($record instanceof LogRecord) {
|
||||
$record = $record->toArray();
|
||||
}
|
||||
|
||||
$record['context'] = $this->cloner->cloneVar($record['context']);
|
||||
$record['extra'] = $this->cloner->cloneVar($record['extra']);
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
public function formatBatch(array $records): mixed
|
||||
{
|
||||
foreach ($records as $k => $record) {
|
||||
$record[$k] = $this->format($record);
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
}
|
||||
73
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ChromePhpHandler.php
vendored
Normal file
73
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ChromePhpHandler.php
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Handler\ChromePHPHandler as BaseChromePhpHandler;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
|
||||
/**
|
||||
* ChromePhpHandler.
|
||||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class ChromePhpHandler extends BaseChromePhpHandler
|
||||
{
|
||||
private array $headers = [];
|
||||
private Response $response;
|
||||
|
||||
/**
|
||||
* Adds the headers to the response once it's created.
|
||||
*/
|
||||
public function onKernelResponse(ResponseEvent $event): void
|
||||
{
|
||||
if (!$event->isMainRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!preg_match(static::USER_AGENT_REGEX, $event->getRequest()->headers->get('User-Agent', ''))) {
|
||||
self::$sendHeaders = false;
|
||||
$this->headers = [];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->response = $event->getResponse();
|
||||
foreach ($this->headers as $header => $content) {
|
||||
$this->response->headers->set($header, $content);
|
||||
}
|
||||
$this->headers = [];
|
||||
}
|
||||
|
||||
protected function sendHeader($header, $content): void
|
||||
{
|
||||
if (!self::$sendHeaders) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($this->response)) {
|
||||
$this->response->headers->set($header, $content);
|
||||
} else {
|
||||
$this->headers[$header] = $content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default behavior since we check it in onKernelResponse.
|
||||
*/
|
||||
protected function headersAccepted(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
51
projects/priceservice/vendor/symfony/monolog-bridge/Handler/CompatibilityHandler.php
vendored
Normal file
51
projects/priceservice/vendor/symfony/monolog-bridge/Handler/CompatibilityHandler.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
|
||||
if (Logger::API >= 3) {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityHandler
|
||||
{
|
||||
abstract private function doHandle(array|LogRecord $record): bool;
|
||||
|
||||
public function handle(LogRecord $record): bool
|
||||
{
|
||||
return $this->doHandle($record);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityHandler
|
||||
{
|
||||
abstract private function doHandle(array|LogRecord $record): bool;
|
||||
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
return $this->doHandle($record);
|
||||
}
|
||||
}
|
||||
}
|
||||
51
projects/priceservice/vendor/symfony/monolog-bridge/Handler/CompatibilityProcessingHandler.php
vendored
Normal file
51
projects/priceservice/vendor/symfony/monolog-bridge/Handler/CompatibilityProcessingHandler.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
|
||||
if (Logger::API >= 3) {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityProcessingHandler
|
||||
{
|
||||
abstract private function doWrite(array|LogRecord $record): void;
|
||||
|
||||
protected function write(LogRecord $record): void
|
||||
{
|
||||
$this->doWrite($record);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityProcessingHandler
|
||||
{
|
||||
abstract private function doWrite(array|LogRecord $record): void;
|
||||
|
||||
protected function write(array $record): void
|
||||
{
|
||||
$this->doWrite($record);
|
||||
}
|
||||
}
|
||||
}
|
||||
225
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ConsoleHandler.php
vendored
Normal file
225
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ConsoleHandler.php
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter;
|
||||
use Symfony\Component\Console\ConsoleEvents;
|
||||
use Symfony\Component\Console\Event\ConsoleCommandEvent;
|
||||
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
|
||||
use Symfony\Component\Console\Output\ConsoleOutputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\VarDumper\Dumper\CliDumper;
|
||||
|
||||
if (Logger::API >= 3) {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityIsHandlingHandler
|
||||
{
|
||||
abstract private function doIsHandling(array|LogRecord $record): bool;
|
||||
|
||||
public function isHandling(LogRecord $record): bool
|
||||
{
|
||||
return $this->doIsHandling($record);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityIsHandlingHandler
|
||||
{
|
||||
abstract private function doIsHandling(array|LogRecord $record): bool;
|
||||
|
||||
public function isHandling(array $record): bool
|
||||
{
|
||||
return $this->doIsHandling($record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes logs to the console output depending on its verbosity setting.
|
||||
*
|
||||
* It is disabled by default and gets activated as soon as a command is executed.
|
||||
* Instead of listening to the console events, the output can also be set manually.
|
||||
*
|
||||
* The minimum logging level at which this handler will be triggered depends on the
|
||||
* verbosity setting of the console output. The default mapping is:
|
||||
* - OutputInterface::VERBOSITY_NORMAL will show all WARNING and higher logs
|
||||
* - OutputInterface::VERBOSITY_VERBOSE (-v) will show all NOTICE and higher logs
|
||||
* - OutputInterface::VERBOSITY_VERY_VERBOSE (-vv) will show all INFO and higher logs
|
||||
* - OutputInterface::VERBOSITY_DEBUG (-vvv) will show all DEBUG and higher logs, i.e. all logs
|
||||
*
|
||||
* This mapping can be customized with the $verbosityLevelMap constructor parameter.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class ConsoleHandler extends AbstractProcessingHandler implements EventSubscriberInterface
|
||||
{
|
||||
use CompatibilityHandler;
|
||||
use CompatibilityIsHandlingHandler;
|
||||
use CompatibilityProcessingHandler;
|
||||
|
||||
private ?OutputInterface $output;
|
||||
private array $verbosityLevelMap = [
|
||||
OutputInterface::VERBOSITY_QUIET => Logger::ERROR,
|
||||
OutputInterface::VERBOSITY_NORMAL => Logger::WARNING,
|
||||
OutputInterface::VERBOSITY_VERBOSE => Logger::NOTICE,
|
||||
OutputInterface::VERBOSITY_VERY_VERBOSE => Logger::INFO,
|
||||
OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG,
|
||||
];
|
||||
private array $consoleFormatterOptions;
|
||||
|
||||
/**
|
||||
* @param OutputInterface|null $output The console output to use (the handler remains disabled when passing null
|
||||
* until the output is set, e.g. by using console events)
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack
|
||||
* @param array $verbosityLevelMap Array that maps the OutputInterface verbosity to a minimum logging
|
||||
* level (leave empty to use the default mapping)
|
||||
*/
|
||||
public function __construct(?OutputInterface $output = null, bool $bubble = true, array $verbosityLevelMap = [], array $consoleFormatterOptions = [])
|
||||
{
|
||||
parent::__construct(Logger::DEBUG, $bubble);
|
||||
$this->output = $output;
|
||||
|
||||
if ($verbosityLevelMap) {
|
||||
$this->verbosityLevelMap = $verbosityLevelMap;
|
||||
}
|
||||
|
||||
$this->consoleFormatterOptions = $consoleFormatterOptions;
|
||||
}
|
||||
|
||||
private function doIsHandling(array|LogRecord $record): bool
|
||||
{
|
||||
return $this->updateLevel() && parent::isHandling($record);
|
||||
}
|
||||
|
||||
private function doHandle(array|LogRecord $record): bool
|
||||
{
|
||||
// we have to update the logging level each time because the verbosity of the
|
||||
// console output might have changed in the meantime (it is not immutable)
|
||||
return $this->updateLevel() && parent::handle($record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the console output to use for printing logs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setOutput(OutputInterface $output)
|
||||
{
|
||||
$this->output = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the output.
|
||||
*/
|
||||
public function close(): void
|
||||
{
|
||||
$this->output = null;
|
||||
|
||||
parent::close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Before a command is executed, the handler gets activated and the console output
|
||||
* is set in order to know where to write the logs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onCommand(ConsoleCommandEvent $event)
|
||||
{
|
||||
$output = $event->getOutput();
|
||||
if ($output instanceof ConsoleOutputInterface) {
|
||||
$output = $output->getErrorOutput();
|
||||
}
|
||||
|
||||
$this->setOutput($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* After a command has been executed, it disables the output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onTerminate(ConsoleTerminateEvent $event)
|
||||
{
|
||||
$this->close();
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
ConsoleEvents::COMMAND => ['onCommand', 255],
|
||||
ConsoleEvents::TERMINATE => ['onTerminate', -255],
|
||||
];
|
||||
}
|
||||
|
||||
private function doWrite(array|LogRecord $record): void
|
||||
{
|
||||
// at this point we've determined for sure that we want to output the record, so use the output's own verbosity
|
||||
$this->output->write((string) $record['formatted'], false, $this->output->getVerbosity());
|
||||
}
|
||||
|
||||
protected function getDefaultFormatter(): FormatterInterface
|
||||
{
|
||||
if (!class_exists(CliDumper::class)) {
|
||||
return new LineFormatter();
|
||||
}
|
||||
if (!$this->output) {
|
||||
return new ConsoleFormatter($this->consoleFormatterOptions);
|
||||
}
|
||||
|
||||
return new ConsoleFormatter(array_replace([
|
||||
'colors' => $this->output->isDecorated(),
|
||||
'multiline' => OutputInterface::VERBOSITY_DEBUG <= $this->output->getVerbosity(),
|
||||
], $this->consoleFormatterOptions));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the logging level based on the verbosity setting of the console output.
|
||||
*
|
||||
* @return bool Whether the handler is enabled and verbosity is not set to quiet
|
||||
*/
|
||||
private function updateLevel(): bool
|
||||
{
|
||||
if (null === $this->output) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$verbosity = $this->output->getVerbosity();
|
||||
if (isset($this->verbosityLevelMap[$verbosity])) {
|
||||
$this->setLevel($this->verbosityLevelMap[$verbosity]);
|
||||
} else {
|
||||
$this->setLevel(Logger::DEBUG);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
189
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ElasticsearchLogstashHandler.php
vendored
Normal file
189
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ElasticsearchLogstashHandler.php
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\LogstashFormatter;
|
||||
use Monolog\Handler\AbstractHandler;
|
||||
use Monolog\Handler\FormattableHandlerTrait;
|
||||
use Monolog\Handler\ProcessableHandlerTrait;
|
||||
use Monolog\Level;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\Exception\ExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
|
||||
/**
|
||||
* Push logs directly to Elasticsearch and format them according to Logstash specification.
|
||||
*
|
||||
* This handler dials directly with the HTTP interface of Elasticsearch. This
|
||||
* means it will slow down your application if Elasticsearch takes times to
|
||||
* answer. Even if all HTTP calls are done asynchronously.
|
||||
*
|
||||
* In a development environment, it's fine to keep the default configuration:
|
||||
* for each log, an HTTP request will be made to push the log to Elasticsearch.
|
||||
*
|
||||
* In a production environment, it's highly recommended to wrap this handler
|
||||
* in a handler with buffering capabilities (like the FingersCrossedHandler, or
|
||||
* BufferHandler) in order to call Elasticsearch only once with a bulk push. For
|
||||
* even better performance and fault tolerance, a proper ELK (https://www.elastic.co/what-is/elk-stack)
|
||||
* stack is recommended.
|
||||
*
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class ElasticsearchLogstashHandler extends AbstractHandler
|
||||
{
|
||||
use CompatibilityHandler;
|
||||
|
||||
use FormattableHandlerTrait;
|
||||
use ProcessableHandlerTrait;
|
||||
|
||||
private string $endpoint;
|
||||
private string $index;
|
||||
private HttpClientInterface $client;
|
||||
private string $elasticsearchVersion;
|
||||
|
||||
/**
|
||||
* @var \SplObjectStorage<ResponseInterface, null>
|
||||
*/
|
||||
private \SplObjectStorage $responses;
|
||||
|
||||
public function __construct(string $endpoint = 'http://127.0.0.1:9200', string $index = 'monolog', ?HttpClientInterface $client = null, string|int|Level $level = Logger::DEBUG, bool $bubble = true, string $elasticsearchVersion = '1.0.0')
|
||||
{
|
||||
if (!interface_exists(HttpClientInterface::class)) {
|
||||
throw new \LogicException(sprintf('The "%s" handler needs an HTTP client. Try running "composer require symfony/http-client".', __CLASS__));
|
||||
}
|
||||
|
||||
parent::__construct($level, $bubble);
|
||||
$this->endpoint = $endpoint;
|
||||
$this->index = $index;
|
||||
$this->client = $client ?: HttpClient::create(['timeout' => 1]);
|
||||
$this->responses = new \SplObjectStorage();
|
||||
$this->elasticsearchVersion = $elasticsearchVersion;
|
||||
}
|
||||
|
||||
private function doHandle(array|LogRecord $record): bool
|
||||
{
|
||||
if (!$this->isHandling($record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->sendToElasticsearch([$record]);
|
||||
|
||||
return !$this->bubble;
|
||||
}
|
||||
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
$records = array_filter($records, $this->isHandling(...));
|
||||
|
||||
if ($records) {
|
||||
$this->sendToElasticsearch($records);
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDefaultFormatter(): FormatterInterface
|
||||
{
|
||||
// Monolog 1.X
|
||||
if (\defined(LogstashFormatter::class.'::V1')) {
|
||||
return new LogstashFormatter('application', null, null, 'ctxt_', LogstashFormatter::V1);
|
||||
}
|
||||
|
||||
// Monolog 2.X
|
||||
return new LogstashFormatter('application');
|
||||
}
|
||||
|
||||
private function sendToElasticsearch(array $records): void
|
||||
{
|
||||
$formatter = $this->getFormatter();
|
||||
|
||||
if (version_compare($this->elasticsearchVersion, '7', '>=')) {
|
||||
$headers = json_encode([
|
||||
'index' => [
|
||||
'_index' => $this->index,
|
||||
],
|
||||
]);
|
||||
} else {
|
||||
$headers = json_encode([
|
||||
'index' => [
|
||||
'_index' => $this->index,
|
||||
'_type' => '_doc',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
$body = '';
|
||||
foreach ($records as $record) {
|
||||
foreach ($this->processors as $processor) {
|
||||
$record = $processor($record);
|
||||
}
|
||||
|
||||
$body .= $headers;
|
||||
$body .= "\n";
|
||||
$body .= $formatter->format($record);
|
||||
$body .= "\n";
|
||||
}
|
||||
|
||||
$response = $this->client->request('POST', $this->endpoint.'/_bulk', [
|
||||
'body' => $body,
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]);
|
||||
|
||||
$this->responses->attach($response);
|
||||
|
||||
$this->wait(false);
|
||||
}
|
||||
|
||||
public function __sleep(): array
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->wait(true);
|
||||
}
|
||||
|
||||
private function wait(bool $blocking): void
|
||||
{
|
||||
foreach ($this->client->stream($this->responses, $blocking ? null : 0.0) as $response => $chunk) {
|
||||
try {
|
||||
if ($chunk->isTimeout() && !$blocking) {
|
||||
continue;
|
||||
}
|
||||
if (!$chunk->isFirst() && !$chunk->isLast()) {
|
||||
continue;
|
||||
}
|
||||
if ($chunk->isLast()) {
|
||||
$this->responses->detach($response);
|
||||
}
|
||||
} catch (ExceptionInterface $e) {
|
||||
$this->responses->detach($response);
|
||||
error_log(sprintf("Could not push logs to Elasticsearch:\n%s", (string) $e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler\FingersCrossed;
|
||||
|
||||
use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
/**
|
||||
* Activation strategy that ignores certain HTTP codes.
|
||||
*
|
||||
* @author Shaun Simmons <shaun@envysphere.com>
|
||||
* @author Pierrick Vignand <pierrick.vignand@gmail.com>
|
||||
*/
|
||||
final class HttpCodeActivationStrategy implements ActivationStrategyInterface
|
||||
{
|
||||
/**
|
||||
* @param array $exclusions each exclusion must have a "code" and "urls" keys
|
||||
*/
|
||||
public function __construct(
|
||||
private RequestStack $requestStack,
|
||||
private array $exclusions,
|
||||
private ActivationStrategyInterface $inner,
|
||||
) {
|
||||
foreach ($exclusions as $exclusion) {
|
||||
if (!\array_key_exists('code', $exclusion)) {
|
||||
throw new \LogicException('An exclusion must have a "code" key.');
|
||||
}
|
||||
if (!\array_key_exists('urls', $exclusion)) {
|
||||
throw new \LogicException('An exclusion must have a "urls" key.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function isHandlerActivated(array|LogRecord $record): bool
|
||||
{
|
||||
$isActivated = $this->inner->isHandlerActivated($record);
|
||||
|
||||
if (
|
||||
$isActivated
|
||||
&& isset($record['context']['exception'])
|
||||
&& $record['context']['exception'] instanceof HttpException
|
||||
&& ($request = $this->requestStack->getMainRequest())
|
||||
) {
|
||||
foreach ($this->exclusions as $exclusion) {
|
||||
if ($record['context']['exception']->getStatusCode() !== $exclusion['code']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (\count($exclusion['urls'])) {
|
||||
return !preg_match('{('.implode('|', $exclusion['urls']).')}i', $request->getPathInfo());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $isActivated;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler\FingersCrossed;
|
||||
|
||||
use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
/**
|
||||
* Activation strategy that ignores 404s for certain URLs.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Pierrick Vignand <pierrick.vignand@gmail.com>
|
||||
*/
|
||||
final class NotFoundActivationStrategy implements ActivationStrategyInterface
|
||||
{
|
||||
private string $exclude;
|
||||
|
||||
public function __construct(
|
||||
private RequestStack $requestStack,
|
||||
array $excludedUrls,
|
||||
private ActivationStrategyInterface $inner
|
||||
) {
|
||||
$this->exclude = '{('.implode('|', $excludedUrls).')}i';
|
||||
}
|
||||
|
||||
public function isHandlerActivated(array|LogRecord $record): bool
|
||||
{
|
||||
$isActivated = $this->inner->isHandlerActivated($record);
|
||||
|
||||
if (
|
||||
$isActivated
|
||||
&& isset($record['context']['exception'])
|
||||
&& $record['context']['exception'] instanceof HttpException
|
||||
&& 404 == $record['context']['exception']->getStatusCode()
|
||||
&& ($request = $this->requestStack->getMainRequest())
|
||||
) {
|
||||
return !preg_match($this->exclude, $request->getPathInfo());
|
||||
}
|
||||
|
||||
return $isActivated;
|
||||
}
|
||||
}
|
||||
75
projects/priceservice/vendor/symfony/monolog-bridge/Handler/FirePHPHandler.php
vendored
Normal file
75
projects/priceservice/vendor/symfony/monolog-bridge/Handler/FirePHPHandler.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Handler\FirePHPHandler as BaseFirePHPHandler;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
|
||||
/**
|
||||
* FirePHPHandler.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class FirePHPHandler extends BaseFirePHPHandler
|
||||
{
|
||||
private array $headers = [];
|
||||
private ?Response $response = null;
|
||||
|
||||
/**
|
||||
* Adds the headers to the response once it's created.
|
||||
*/
|
||||
public function onKernelResponse(ResponseEvent $event): void
|
||||
{
|
||||
if (!$event->isMainRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
if (!preg_match('{\bFirePHP/\d+\.\d+\b}', $request->headers->get('User-Agent', ''))
|
||||
&& !$request->headers->has('X-FirePHP-Version')) {
|
||||
self::$sendHeaders = false;
|
||||
$this->headers = [];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->response = $event->getResponse();
|
||||
foreach ($this->headers as $header => $content) {
|
||||
$this->response->headers->set($header, $content);
|
||||
}
|
||||
$this->headers = [];
|
||||
}
|
||||
|
||||
protected function sendHeader($header, $content): void
|
||||
{
|
||||
if (!self::$sendHeaders) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null !== $this->response) {
|
||||
$this->response->headers->set($header, $content);
|
||||
} else {
|
||||
$this->headers[$header] = $content;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default behavior since we check the user agent in onKernelResponse.
|
||||
*/
|
||||
protected function headersAccepted(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
150
projects/priceservice/vendor/symfony/monolog-bridge/Handler/MailerHandler.php
vendored
Normal file
150
projects/priceservice/vendor/symfony/monolog-bridge/Handler/MailerHandler.php
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Formatter\HtmlFormatter;
|
||||
use Monolog\Formatter\LineFormatter;
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Monolog\Level;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\Mailer\MailerInterface;
|
||||
use Symfony\Component\Mime\Email;
|
||||
|
||||
/**
|
||||
* @author Alexander Borisov <boshurik@gmail.com>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class MailerHandler extends AbstractProcessingHandler
|
||||
{
|
||||
use CompatibilityProcessingHandler;
|
||||
|
||||
private MailerInterface $mailer;
|
||||
private \Closure|Email $messageTemplate;
|
||||
|
||||
public function __construct(MailerInterface $mailer, callable|Email $messageTemplate, string|int|Level $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
|
||||
$this->mailer = $mailer;
|
||||
$this->messageTemplate = $messageTemplate instanceof Email ? $messageTemplate : $messageTemplate(...);
|
||||
}
|
||||
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
$messages = [];
|
||||
|
||||
if (Logger::API >= 3) {
|
||||
/** @var LogRecord $record */
|
||||
foreach ($records as $record) {
|
||||
if ($record->level->isLowerThan($this->level)) {
|
||||
continue;
|
||||
}
|
||||
$messages[] = $this->processRecord($record);
|
||||
}
|
||||
} else {
|
||||
foreach ($records as $record) {
|
||||
if ($record['level'] < $this->level) {
|
||||
continue;
|
||||
}
|
||||
$messages[] = $this->processRecord($record);
|
||||
}
|
||||
}
|
||||
|
||||
if ($messages) {
|
||||
$this->send((string) $this->getFormatter()->formatBatch($messages), $messages);
|
||||
}
|
||||
}
|
||||
|
||||
private function doWrite(array|LogRecord $record): void
|
||||
{
|
||||
$this->send((string) $record['formatted'], [$record]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a mail with the given content.
|
||||
*
|
||||
* @param string $content formatted email body to be sent
|
||||
* @param array $records the array of log records that formed this content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function send(string $content, array $records)
|
||||
{
|
||||
$this->mailer->send($this->buildMessage($content, $records));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatter for the Message subject.
|
||||
*
|
||||
* @param string $format The format of the subject
|
||||
*/
|
||||
protected function getSubjectFormatter(string $format): FormatterInterface
|
||||
{
|
||||
return new LineFormatter($format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates instance of Message to be sent.
|
||||
*
|
||||
* @param string $content formatted email body to be sent
|
||||
* @param array $records Log records that formed the content
|
||||
*/
|
||||
protected function buildMessage(string $content, array $records): Email
|
||||
{
|
||||
if ($this->messageTemplate instanceof Email) {
|
||||
$message = clone $this->messageTemplate;
|
||||
} elseif (\is_callable($this->messageTemplate)) {
|
||||
$message = ($this->messageTemplate)($content, $records);
|
||||
if (!$message instanceof Email) {
|
||||
throw new \InvalidArgumentException(sprintf('Could not resolve message from a callable. Instance of "%s" is expected.', Email::class));
|
||||
}
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Could not resolve message as instance of Email or a callable returning it.');
|
||||
}
|
||||
|
||||
if ($records) {
|
||||
$subjectFormatter = $this->getSubjectFormatter($message->getSubject());
|
||||
$message->subject($subjectFormatter->format($this->getHighestRecord($records)));
|
||||
}
|
||||
|
||||
if ($this->getFormatter() instanceof HtmlFormatter) {
|
||||
if ($message->getHtmlCharset()) {
|
||||
$message->html($content, $message->getHtmlCharset());
|
||||
} else {
|
||||
$message->html($content);
|
||||
}
|
||||
} else {
|
||||
if ($message->getTextCharset()) {
|
||||
$message->text($content, $message->getTextCharset());
|
||||
} else {
|
||||
$message->text($content);
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
protected function getHighestRecord(array $records): array|LogRecord
|
||||
{
|
||||
$highestRecord = null;
|
||||
foreach ($records as $record) {
|
||||
if (null === $highestRecord || $highestRecord['level'] < $record['level']) {
|
||||
$highestRecord = $record;
|
||||
}
|
||||
}
|
||||
|
||||
return $highestRecord;
|
||||
}
|
||||
}
|
||||
85
projects/priceservice/vendor/symfony/monolog-bridge/Handler/NotifierHandler.php
vendored
Normal file
85
projects/priceservice/vendor/symfony/monolog-bridge/Handler/NotifierHandler.php
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Handler\AbstractHandler;
|
||||
use Monolog\Level;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\Notifier\Notification\Notification;
|
||||
use Symfony\Component\Notifier\Notifier;
|
||||
use Symfony\Component\Notifier\NotifierInterface;
|
||||
|
||||
/**
|
||||
* Uses Notifier as a log handler.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class NotifierHandler extends AbstractHandler
|
||||
{
|
||||
use CompatibilityHandler;
|
||||
|
||||
private NotifierInterface $notifier;
|
||||
|
||||
public function __construct(NotifierInterface $notifier, string|int|Level $level = Logger::ERROR, bool $bubble = true)
|
||||
{
|
||||
$this->notifier = $notifier;
|
||||
|
||||
parent::__construct(Logger::toMonologLevel($level) < Logger::ERROR ? Logger::ERROR : $level, $bubble);
|
||||
}
|
||||
|
||||
private function doHandle(array|LogRecord $record): bool
|
||||
{
|
||||
if (!$this->isHandling($record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->notify([$record]);
|
||||
|
||||
return !$this->bubble;
|
||||
}
|
||||
|
||||
public function handleBatch(array $records): void
|
||||
{
|
||||
if ($records = array_filter($records, $this->isHandling(...))) {
|
||||
$this->notify($records);
|
||||
}
|
||||
}
|
||||
|
||||
private function notify(array $records): void
|
||||
{
|
||||
$record = $this->getHighestRecord($records);
|
||||
if (($record['context']['exception'] ?? null) instanceof \Throwable) {
|
||||
$notification = Notification::fromThrowable($record['context']['exception']);
|
||||
} else {
|
||||
$notification = new Notification($record['message']);
|
||||
}
|
||||
|
||||
$notification->importanceFromLogLevelName(Logger::getLevelName($record['level']));
|
||||
|
||||
$this->notifier->send($notification, ...$this->notifier->getAdminRecipients());
|
||||
}
|
||||
|
||||
private function getHighestRecord(array $records): array|LogRecord
|
||||
{
|
||||
$highestRecord = null;
|
||||
foreach ($records as $record) {
|
||||
if (null === $highestRecord || $highestRecord['level'] < $record['level']) {
|
||||
$highestRecord = $record;
|
||||
}
|
||||
}
|
||||
|
||||
return $highestRecord;
|
||||
}
|
||||
}
|
||||
156
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ServerLogHandler.php
vendored
Normal file
156
projects/priceservice/vendor/symfony/monolog-bridge/Handler/ServerLogHandler.php
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Handler;
|
||||
|
||||
use Monolog\Formatter\FormatterInterface;
|
||||
use Monolog\Handler\AbstractProcessingHandler;
|
||||
use Monolog\Handler\FormattableHandlerTrait;
|
||||
use Monolog\Level;
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter;
|
||||
|
||||
if (trait_exists(FormattableHandlerTrait::class)) {
|
||||
/**
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class ServerLogHandler extends AbstractProcessingHandler
|
||||
{
|
||||
use CompatibilityHandler;
|
||||
use CompatibilityProcessingHandler;
|
||||
use ServerLogHandlerTrait;
|
||||
|
||||
protected function getDefaultFormatter(): FormatterInterface
|
||||
{
|
||||
return new VarDumperFormatter();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class ServerLogHandler extends AbstractProcessingHandler
|
||||
{
|
||||
use CompatibilityHandler;
|
||||
use CompatibilityProcessingHandler;
|
||||
use ServerLogHandlerTrait;
|
||||
|
||||
protected function getDefaultFormatter()
|
||||
{
|
||||
return new VarDumperFormatter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Grégoire Pineau <lyrixx@lyrixx.info>
|
||||
*
|
||||
* @internal since Symfony 6.1
|
||||
*/
|
||||
trait ServerLogHandlerTrait
|
||||
{
|
||||
private string $host;
|
||||
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
private $context;
|
||||
|
||||
/**
|
||||
* @var resource|null
|
||||
*/
|
||||
private $socket;
|
||||
|
||||
public function __construct(string $host, string|int|Level $level = Logger::DEBUG, bool $bubble = true, array $context = [])
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
|
||||
if (!str_contains($host, '://')) {
|
||||
$host = 'tcp://'.$host;
|
||||
}
|
||||
|
||||
$this->host = $host;
|
||||
$this->context = stream_context_create($context);
|
||||
}
|
||||
|
||||
private function doHandle(array|LogRecord $record): bool
|
||||
{
|
||||
if (!$this->isHandling($record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
set_error_handler(static fn () => null);
|
||||
|
||||
try {
|
||||
if (!$this->socket = $this->socket ?: $this->createSocket()) {
|
||||
return false === $this->bubble;
|
||||
}
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
return parent::handle($record);
|
||||
}
|
||||
|
||||
private function doWrite(array|LogRecord $record): void
|
||||
{
|
||||
$recordFormatted = $this->formatRecord($record);
|
||||
|
||||
set_error_handler(static fn () => null);
|
||||
|
||||
try {
|
||||
if (-1 === stream_socket_sendto($this->socket, $recordFormatted)) {
|
||||
stream_socket_shutdown($this->socket, \STREAM_SHUT_RDWR);
|
||||
|
||||
// Let's retry: the persistent connection might just be stale
|
||||
if ($this->socket = $this->createSocket()) {
|
||||
stream_socket_sendto($this->socket, $recordFormatted);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
restore_error_handler();
|
||||
}
|
||||
}
|
||||
|
||||
protected function getDefaultFormatter(): FormatterInterface
|
||||
{
|
||||
return new VarDumperFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
private function createSocket()
|
||||
{
|
||||
$socket = stream_socket_client($this->host, $errno, $errstr, 0, \STREAM_CLIENT_CONNECT | \STREAM_CLIENT_ASYNC_CONNECT | \STREAM_CLIENT_PERSISTENT, $this->context);
|
||||
|
||||
if ($socket) {
|
||||
stream_set_blocking($socket, false);
|
||||
}
|
||||
|
||||
return $socket;
|
||||
}
|
||||
|
||||
private function formatRecord(array|LogRecord $record): string
|
||||
{
|
||||
$recordFormatted = $record['formatted'];
|
||||
|
||||
foreach (['log_uuid', 'uuid', 'uid'] as $key) {
|
||||
if (isset($record['extra'][$key])) {
|
||||
$recordFormatted['log_id'] = $record['extra'][$key];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return base64_encode(serialize($recordFormatted))."\n";
|
||||
}
|
||||
}
|
||||
19
projects/priceservice/vendor/symfony/monolog-bridge/LICENSE
vendored
Normal file
19
projects/priceservice/vendor/symfony/monolog-bridge/LICENSE
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2004-present Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
98
projects/priceservice/vendor/symfony/monolog-bridge/Logger.php
vendored
Normal file
98
projects/priceservice/vendor/symfony/monolog-bridge/Logger.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog;
|
||||
|
||||
trigger_deprecation('symfony/monolog-bridge', '6.4', 'The "%s" class is deprecated, use HttpKernel\'s DebugLoggerConfigurator instead.', Logger::class);
|
||||
|
||||
use Monolog\Logger as BaseLogger;
|
||||
use Monolog\ResettableInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 6.4, use HttpKernel's DebugLoggerConfigurator instead
|
||||
*/
|
||||
class Logger extends BaseLogger implements DebugLoggerInterface, ResetInterface
|
||||
{
|
||||
public function getLogs(?Request $request = null): array
|
||||
{
|
||||
if ($logger = $this->getDebugLogger()) {
|
||||
return $logger->getLogs($request);
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function countErrors(?Request $request = null): int
|
||||
{
|
||||
if ($logger = $this->getDebugLogger()) {
|
||||
return $logger->countErrors($request);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
if ($logger = $this->getDebugLogger()) {
|
||||
$logger->clear();
|
||||
}
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->clear();
|
||||
|
||||
if ($this instanceof ResettableInterface) {
|
||||
parent::reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function removeDebugLogger()
|
||||
{
|
||||
foreach ($this->processors as $k => $processor) {
|
||||
if ($processor instanceof DebugLoggerInterface) {
|
||||
unset($this->processors[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->handlers as $k => $handler) {
|
||||
if ($handler instanceof DebugLoggerInterface) {
|
||||
unset($this->handlers[$k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DebugLoggerInterface instance if one is registered with this logger.
|
||||
*/
|
||||
private function getDebugLogger(): ?DebugLoggerInterface
|
||||
{
|
||||
foreach ($this->processors as $processor) {
|
||||
if ($processor instanceof DebugLoggerInterface) {
|
||||
return $processor;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->handlers as $handler) {
|
||||
if ($handler instanceof DebugLoggerInterface) {
|
||||
return $handler;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
60
projects/priceservice/vendor/symfony/monolog-bridge/Processor/AbstractTokenProcessor.php
vendored
Normal file
60
projects/priceservice/vendor/symfony/monolog-bridge/Processor/AbstractTokenProcessor.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* The base class for security token processors.
|
||||
*
|
||||
* @author Dany Maillard <danymaillard93b@gmail.com>
|
||||
* @author Igor Timoshenko <igor.timoshenko@i.ua>
|
||||
*
|
||||
* @internal since Symfony 6.1
|
||||
*/
|
||||
abstract class AbstractTokenProcessor
|
||||
{
|
||||
use CompatibilityProcessor;
|
||||
|
||||
/**
|
||||
* @var TokenStorageInterface
|
||||
*/
|
||||
protected $tokenStorage;
|
||||
|
||||
public function __construct(TokenStorageInterface $tokenStorage)
|
||||
{
|
||||
$this->tokenStorage = $tokenStorage;
|
||||
}
|
||||
|
||||
abstract protected function getKey(): string;
|
||||
|
||||
abstract protected function getToken(): ?TokenInterface;
|
||||
|
||||
private function doInvoke(array|LogRecord $record): array|LogRecord
|
||||
{
|
||||
$record['extra'][$this->getKey()] = null;
|
||||
|
||||
if (null !== $token = $this->getToken()) {
|
||||
$record['extra'][$this->getKey()] = [
|
||||
'authenticated' => (bool) $token->getUser(),
|
||||
'roles' => $token->getRoleNames(),
|
||||
];
|
||||
|
||||
// @deprecated since Symfony 5.3, change to $token->getUserIdentifier() in 7.0
|
||||
$record['extra'][$this->getKey()]['user_identifier'] = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
51
projects/priceservice/vendor/symfony/monolog-bridge/Processor/CompatibilityProcessor.php
vendored
Normal file
51
projects/priceservice/vendor/symfony/monolog-bridge/Processor/CompatibilityProcessor.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
|
||||
if (Logger::API >= 3) {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityProcessor
|
||||
{
|
||||
abstract private function doInvoke(array|LogRecord $record): array|LogRecord;
|
||||
|
||||
public function __invoke(LogRecord $record): LogRecord
|
||||
{
|
||||
return $this->doInvoke($record);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* The base class for compatibility between Monolog 3 LogRecord and Monolog 1/2 array records.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
trait CompatibilityProcessor
|
||||
{
|
||||
abstract private function doInvoke(array|LogRecord $record): array|LogRecord;
|
||||
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
return $this->doInvoke($record);
|
||||
}
|
||||
}
|
||||
}
|
||||
80
projects/priceservice/vendor/symfony/monolog-bridge/Processor/ConsoleCommandProcessor.php
vendored
Normal file
80
projects/priceservice/vendor/symfony/monolog-bridge/Processor/ConsoleCommandProcessor.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\Console\ConsoleEvents;
|
||||
use Symfony\Component\Console\Event\ConsoleEvent;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
/**
|
||||
* Adds the current console command information to the log entry.
|
||||
*
|
||||
* @author Piotr Stankowski <git@trakos.pl>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class ConsoleCommandProcessor implements EventSubscriberInterface, ResetInterface
|
||||
{
|
||||
use CompatibilityProcessor;
|
||||
|
||||
private array $commandData;
|
||||
private bool $includeArguments;
|
||||
private bool $includeOptions;
|
||||
|
||||
public function __construct(bool $includeArguments = true, bool $includeOptions = false)
|
||||
{
|
||||
$this->includeArguments = $includeArguments;
|
||||
$this->includeOptions = $includeOptions;
|
||||
}
|
||||
|
||||
private function doInvoke(array|LogRecord $record): array|LogRecord
|
||||
{
|
||||
if (isset($this->commandData) && !isset($record['extra']['command'])) {
|
||||
$record['extra']['command'] = $this->commandData;
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
unset($this->commandData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function addCommandData(ConsoleEvent $event)
|
||||
{
|
||||
$this->commandData = [
|
||||
'name' => $event->getCommand()->getName(),
|
||||
];
|
||||
if ($this->includeArguments) {
|
||||
$this->commandData['arguments'] = $event->getInput()->getArguments();
|
||||
}
|
||||
if ($this->includeOptions) {
|
||||
$this->commandData['options'] = $event->getInput()->getOptions();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
ConsoleEvents::COMMAND => ['addCommandData', 1],
|
||||
];
|
||||
}
|
||||
}
|
||||
106
projects/priceservice/vendor/symfony/monolog-bridge/Processor/DebugProcessor.php
vendored
Normal file
106
projects/priceservice/vendor/symfony/monolog-bridge/Processor/DebugProcessor.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Monolog\Logger;
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
class DebugProcessor implements DebugLoggerInterface, ResetInterface
|
||||
{
|
||||
use CompatibilityProcessor;
|
||||
|
||||
private array $records = [];
|
||||
private array $errorCount = [];
|
||||
private ?RequestStack $requestStack;
|
||||
|
||||
public function __construct(?RequestStack $requestStack = null)
|
||||
{
|
||||
$this->requestStack = $requestStack;
|
||||
}
|
||||
|
||||
private function doInvoke(array|LogRecord $record): array|LogRecord
|
||||
{
|
||||
$key = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_id($request) : '';
|
||||
|
||||
$timestampRfc3339 = false;
|
||||
if ($record['datetime'] instanceof \DateTimeInterface) {
|
||||
$timestamp = $record['datetime']->getTimestamp();
|
||||
$timestampRfc3339 = $record['datetime']->format(\DateTimeInterface::RFC3339_EXTENDED);
|
||||
} elseif (false !== $timestamp = strtotime($record['datetime'])) {
|
||||
$timestampRfc3339 = (new \DateTimeImmutable($record['datetime']))->format(\DateTimeInterface::RFC3339_EXTENDED);
|
||||
}
|
||||
|
||||
$this->records[$key][] = [
|
||||
'timestamp' => $timestamp,
|
||||
'timestamp_rfc3339' => $timestampRfc3339,
|
||||
'message' => $record['message'],
|
||||
'priority' => $record['level'],
|
||||
'priorityName' => $record['level_name'],
|
||||
'context' => $record['context'],
|
||||
'channel' => $record['channel'] ?? '',
|
||||
];
|
||||
|
||||
if (!isset($this->errorCount[$key])) {
|
||||
$this->errorCount[$key] = 0;
|
||||
}
|
||||
|
||||
switch ($record['level']) {
|
||||
case Logger::ERROR:
|
||||
case Logger::CRITICAL:
|
||||
case Logger::ALERT:
|
||||
case Logger::EMERGENCY:
|
||||
++$this->errorCount[$key];
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
public function getLogs(?Request $request = null): array
|
||||
{
|
||||
if (null !== $request) {
|
||||
return $this->records[spl_object_id($request)] ?? [];
|
||||
}
|
||||
|
||||
if (0 === \count($this->records)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return array_merge(...array_values($this->records));
|
||||
}
|
||||
|
||||
public function countErrors(?Request $request = null): int
|
||||
{
|
||||
if (null !== $request) {
|
||||
return $this->errorCount[spl_object_id($request)] ?? 0;
|
||||
}
|
||||
|
||||
return array_sum($this->errorCount);
|
||||
}
|
||||
|
||||
public function clear(): void
|
||||
{
|
||||
$this->records = [];
|
||||
$this->errorCount = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->clear();
|
||||
}
|
||||
}
|
||||
89
projects/priceservice/vendor/symfony/monolog-bridge/Processor/RouteProcessor.php
vendored
Normal file
89
projects/priceservice/vendor/symfony/monolog-bridge/Processor/RouteProcessor.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Monolog\LogRecord;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Contracts\Service\ResetInterface;
|
||||
|
||||
/**
|
||||
* Adds the current route information to the log entry.
|
||||
*
|
||||
* @author Piotr Stankowski <git@trakos.pl>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class RouteProcessor implements EventSubscriberInterface, ResetInterface
|
||||
{
|
||||
private array $routeData = [];
|
||||
private bool $includeParams;
|
||||
|
||||
public function __construct(bool $includeParams = true)
|
||||
{
|
||||
$this->includeParams = $includeParams;
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
public function __invoke(array|LogRecord $record): array|LogRecord
|
||||
{
|
||||
if ($this->routeData && !isset($record['extra']['requests'])) {
|
||||
$record['extra']['requests'] = array_values($this->routeData);
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
public function reset(): void
|
||||
{
|
||||
$this->routeData = [];
|
||||
}
|
||||
|
||||
public function addRouteData(RequestEvent $event): void
|
||||
{
|
||||
if ($event->isMainRequest()) {
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
$request = $event->getRequest();
|
||||
if (!$request->attributes->has('_controller')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$currentRequestData = [
|
||||
'controller' => $request->attributes->get('_controller'),
|
||||
'route' => $request->attributes->get('_route'),
|
||||
];
|
||||
|
||||
if ($this->includeParams) {
|
||||
$currentRequestData['route_params'] = $request->attributes->get('_route_params');
|
||||
}
|
||||
|
||||
$this->routeData[spl_object_id($request)] = $currentRequestData;
|
||||
}
|
||||
|
||||
public function removeRouteData(FinishRequestEvent $event): void
|
||||
{
|
||||
$requestId = spl_object_id($event->getRequest());
|
||||
unset($this->routeData[$requestId]);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
KernelEvents::REQUEST => ['addRouteData', 1],
|
||||
KernelEvents::FINISH_REQUEST => ['removeRouteData', 1],
|
||||
];
|
||||
}
|
||||
}
|
||||
41
projects/priceservice/vendor/symfony/monolog-bridge/Processor/SwitchUserTokenProcessor.php
vendored
Normal file
41
projects/priceservice/vendor/symfony/monolog-bridge/Processor/SwitchUserTokenProcessor.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* Adds the original security token to the log entry.
|
||||
*
|
||||
* @author Igor Timoshenko <igor.timoshenko@i.ua>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class SwitchUserTokenProcessor extends AbstractTokenProcessor
|
||||
{
|
||||
protected function getKey(): string
|
||||
{
|
||||
return 'impersonator_token';
|
||||
}
|
||||
|
||||
protected function getToken(): ?TokenInterface
|
||||
{
|
||||
$token = $this->tokenStorage->getToken();
|
||||
|
||||
if ($token instanceof SwitchUserToken) {
|
||||
return $token->getOriginalToken();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
35
projects/priceservice/vendor/symfony/monolog-bridge/Processor/TokenProcessor.php
vendored
Normal file
35
projects/priceservice/vendor/symfony/monolog-bridge/Processor/TokenProcessor.php
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
/**
|
||||
* Adds the current security token to the log entry.
|
||||
*
|
||||
* @author Dany Maillard <danymaillard93b@gmail.com>
|
||||
* @author Igor Timoshenko <igor.timoshenko@i.ua>
|
||||
*
|
||||
* @final since Symfony 6.1
|
||||
*/
|
||||
class TokenProcessor extends AbstractTokenProcessor
|
||||
{
|
||||
protected function getKey(): string
|
||||
{
|
||||
return 'token';
|
||||
}
|
||||
|
||||
protected function getToken(): ?TokenInterface
|
||||
{
|
||||
return $this->tokenStorage->getToken();
|
||||
}
|
||||
}
|
||||
48
projects/priceservice/vendor/symfony/monolog-bridge/Processor/WebProcessor.php
vendored
Normal file
48
projects/priceservice/vendor/symfony/monolog-bridge/Processor/WebProcessor.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Bridge\Monolog\Processor;
|
||||
|
||||
use Monolog\Processor\WebProcessor as BaseWebProcessor;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* WebProcessor override to read from the HttpFoundation's Request.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
class WebProcessor extends BaseWebProcessor implements EventSubscriberInterface
|
||||
{
|
||||
public function __construct(?array $extraFields = null)
|
||||
{
|
||||
// Pass an empty array as the default null value would access $_SERVER
|
||||
parent::__construct([], $extraFields);
|
||||
}
|
||||
|
||||
public function onKernelRequest(RequestEvent $event): void
|
||||
{
|
||||
if ($event->isMainRequest()) {
|
||||
$this->serverData = $event->getRequest()->server->all();
|
||||
$this->serverData['REMOTE_ADDR'] = $event->getRequest()->getClientIp();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
KernelEvents::REQUEST => ['onKernelRequest', 4096],
|
||||
];
|
||||
}
|
||||
}
|
||||
13
projects/priceservice/vendor/symfony/monolog-bridge/README.md
vendored
Normal file
13
projects/priceservice/vendor/symfony/monolog-bridge/README.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Monolog Bridge
|
||||
==============
|
||||
|
||||
The Monolog bridge provides integration for
|
||||
[Monolog](https://seldaek.github.io/monolog/) with various Symfony components.
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
|
||||
* [Report issues](https://github.com/symfony/symfony/issues) and
|
||||
[send Pull Requests](https://github.com/symfony/symfony/pulls)
|
||||
in the [main Symfony repository](https://github.com/symfony/symfony)
|
||||
46
projects/priceservice/vendor/symfony/monolog-bridge/composer.json
vendored
Normal file
46
projects/priceservice/vendor/symfony/monolog-bridge/composer.json
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "symfony/monolog-bridge",
|
||||
"type": "symfony-bridge",
|
||||
"description": "Provides integration for Monolog with various Symfony components",
|
||||
"keywords": [],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"monolog/monolog": "^1.25.1|^2|^3",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/http-kernel": "^5.4|^6.0|^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^5.4|^6.0|^7.0",
|
||||
"symfony/http-client": "^5.4|^6.0|^7.0",
|
||||
"symfony/security-core": "^5.4|^6.0|^7.0",
|
||||
"symfony/var-dumper": "^5.4|^6.0|^7.0",
|
||||
"symfony/mailer": "^5.4|^6.0|^7.0",
|
||||
"symfony/mime": "^5.4|^6.0|^7.0",
|
||||
"symfony/messenger": "^5.4|^6.0|^7.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<5.4",
|
||||
"symfony/http-foundation": "<5.4",
|
||||
"symfony/security-core": "<5.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Bridge\\Monolog\\": "" },
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
Reference in New Issue
Block a user