update
This commit is contained in:
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";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user