FestinHegre/vendor/symfony/monolog-bridge/Handler/ServerLogHandler.php
2024-09-26 17:26:04 +02:00

123 lines
3.1 KiB
PHP

<?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\Level;
use Monolog\LogRecord;
use Symfony\Bridge\Monolog\Formatter\VarDumperFormatter;
/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*
* @internal
*/
final class ServerLogHandler extends AbstractProcessingHandler
{
private string $host;
/**
* @var resource
*/
private $context;
/**
* @var resource|null
*/
private $socket;
public function __construct(string $host, string|int|Level $level = Level::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);
}
public function handle(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);
}
protected function write(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(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";
}
}