Compare commits
No commits in common. 'production' and '0.1.4' have entirely different histories.
production
...
0.1.4
File diff suppressed because it is too large
Load Diff
@ -1,95 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ae3\LaravelLogsLayer\app\Handlers;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Monolog\Handler\AbstractProcessingHandler;
|
|
||||||
use Monolog\LogRecord;
|
|
||||||
use PhpAmqpLib\Channel\AbstractChannel;
|
|
||||||
use PhpAmqpLib\Channel\AMQPChannel;
|
|
||||||
use PhpAmqpLib\Connection\AMQPStreamConnection;
|
|
||||||
use PhpAmqpLib\Message\AMQPMessage;
|
|
||||||
|
|
||||||
class RabbitMQHandler extends AbstractProcessingHandler
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var AMQPStreamConnection
|
|
||||||
*/
|
|
||||||
private AMQPStreamConnection $connection;
|
|
||||||
/**
|
|
||||||
* @var AbstractChannel|AMQPChannel
|
|
||||||
*/
|
|
||||||
private $channel;
|
|
||||||
/**
|
|
||||||
* @var mixed|string
|
|
||||||
*/
|
|
||||||
private $exchange;
|
|
||||||
/**
|
|
||||||
* @var mixed|string
|
|
||||||
*/
|
|
||||||
private $routingKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function __construct($exchange = 'logs', $routingKey = 'log', $level = 400, $bubble = true)
|
|
||||||
{
|
|
||||||
parent::__construct($level, $bubble);
|
|
||||||
|
|
||||||
$this->connection = new AMQPStreamConnection(
|
|
||||||
config('logging.channels.rabbitmq.host'),
|
|
||||||
config('logging.channels.rabbitmq.port'),
|
|
||||||
config('logging.channels.rabbitmq.username'),
|
|
||||||
config('logging.channels.rabbitmq.password')
|
|
||||||
);
|
|
||||||
$this->channel = $this->connection->channel();
|
|
||||||
|
|
||||||
$this->exchange = $exchange;
|
|
||||||
$this->routingKey = $routingKey;
|
|
||||||
$this->channel->exchange_declare($exchange, 'direct', false, true, false);
|
|
||||||
|
|
||||||
$queueName = config('logging.channels.rabbitmq.queue', 'logstash_queue');
|
|
||||||
$this->channel->queue_declare($queueName, false, true, false, false);
|
|
||||||
$this->channel->queue_bind($queueName, $this->exchange, $this->routingKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $record
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function write($record): void
|
|
||||||
{
|
|
||||||
if (is_array($record)) {
|
|
||||||
// Implementação para Monolog 1.x
|
|
||||||
$this->recordHandler($record);
|
|
||||||
}elseif (class_exists(LogRecord::class) && $record instanceof LogRecord) {
|
|
||||||
// Implementação para Monolog 2.x
|
|
||||||
$arrayRecord = $record->toArray();
|
|
||||||
$this->recordHandler($arrayRecord);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $record
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function recordHandler(array $record)
|
|
||||||
{
|
|
||||||
$data = json_encode($record);
|
|
||||||
$msg = new AMQPMessage($data, [
|
|
||||||
'delivery_mode' => 2
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->channel->basic_publish($msg, $this->exchange, $this->routingKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function close(): void
|
|
||||||
{
|
|
||||||
$this->channel->close();
|
|
||||||
$this->connection->close();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ae3\LaravelLogsLayer\app\Jobs;
|
|
||||||
|
|
||||||
use Ae3\LaravelLogsLayer\app\Exceptions\InvalidArgumentException;
|
|
||||||
use GuzzleHttp\Exception\GuzzleException;
|
|
||||||
use Illuminate\Bus\Queueable;
|
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
|
||||||
use Illuminate\Queue\SerializesModels;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
class ProcessLog implements ShouldQueue
|
|
||||||
{
|
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected string $channel;
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected string $level;
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected string $message;
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected array $data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $channel
|
|
||||||
* @param string $level
|
|
||||||
* @param string $message
|
|
||||||
* @param array $data
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
string $channel,
|
|
||||||
string $level,
|
|
||||||
string $message,
|
|
||||||
array $data
|
|
||||||
)
|
|
||||||
{
|
|
||||||
$this->level = $level;
|
|
||||||
$this->message = $message;
|
|
||||||
$this->data = $data;
|
|
||||||
$this->channel = $channel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine the time at which the job should timeout.
|
|
||||||
*/
|
|
||||||
public function retryUntil(): \DateTime
|
|
||||||
{
|
|
||||||
return now()->addMinutes(config('laravel-logs-layer.queue.retry_until_in_minutes', 60));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate the number of seconds to wait before retrying the job.
|
|
||||||
*
|
|
||||||
* @return array<int, int>
|
|
||||||
*/
|
|
||||||
public function backoff(): array
|
|
||||||
{
|
|
||||||
return array_map('intval', config('laravel-logs-layer.queue.backoff', ['5','10','20','40']));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function handle(): void
|
|
||||||
{
|
|
||||||
$level = $this->level;
|
|
||||||
Log::channel($this->channel)->$level($this->message, $this->data);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ae3\LaravelLogsLayer\app\Loggers;
|
|
||||||
|
|
||||||
use Ae3\LaravelLogsLayer\app\Exceptions\MissingConfigurationException;
|
|
||||||
use Ae3\LaravelLogsLayer\app\Handlers\RabbitMQHandler;
|
|
||||||
use Exception;
|
|
||||||
use Monolog\Logger;
|
|
||||||
|
|
||||||
class RabbitMQLogger extends AbstractLogger
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @param array $config
|
|
||||||
* @return void
|
|
||||||
* @throws MissingConfigurationException
|
|
||||||
*/
|
|
||||||
public function validateConfig(array $config): void
|
|
||||||
{
|
|
||||||
$requiredKeys = ['host', 'port', 'username', 'password'];
|
|
||||||
|
|
||||||
foreach (array_merge($requiredKeys, $this->requiredKeys) as $key) {
|
|
||||||
if (!array_key_exists($key, $config)) {
|
|
||||||
throw new MissingConfigurationException("Missing configuration key: $key in rabbitmq channel");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function createLogger(array $config): Logger
|
|
||||||
{
|
|
||||||
$handler = new RabbitMQHandler(
|
|
||||||
$config['exchange'] ?? 'logs',
|
|
||||||
$config['routing_key'] ?? 'log',
|
|
||||||
$config['level'] ?? Logger::DEBUG,
|
|
||||||
$config['bubble'] ?? true
|
|
||||||
);
|
|
||||||
|
|
||||||
return new Logger('rabbitmq', [$handler]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Ae3\LaravelLogsLayer\app\Services;
|
|
||||||
|
|
||||||
use Ae3\LaravelLogsLayer\app\DataTransferObjects\ExceptionContextDTO;
|
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
class RabbitMQLogService extends AbstractLogService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
protected function getLogChannel(): string
|
|
||||||
{
|
|
||||||
return 'rabbitmq';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
protected function buildLogData(string $caller, Throwable $exception, ExceptionContextDTO $contextDto): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'caller' => $caller,
|
|
||||||
'status_code' => $exception->getCode(),
|
|
||||||
'line' => $exception->getLine(),
|
|
||||||
'file' => $exception->getFile(),
|
|
||||||
'error_code' => $contextDto->code,
|
|
||||||
'custom_data' => $this->asPrettyJson($contextDto->custom_data),
|
|
||||||
'tags' => $contextDto->tags,
|
|
||||||
'exception' => get_class($exception),
|
|
||||||
'current_url' => $contextDto->current_url,
|
|
||||||
'current_user' => $this->asPrettyJson($contextDto->current_user),
|
|
||||||
'classes' => $this->asPrettyJson($this->getContextClasses($exception->getTrace(), $contextDto->root_namespace)),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue