From 4b433b0375aeac3a9a854263c6c48fde568d6488 Mon Sep 17 00:00:00 2001
From: Andrew <33055211+andrew-nuwber@users.noreply.github.com>
Date: Mon, 14 Aug 2023 10:33:41 +0200
Subject: [PATCH] Print exception data to console output (#118)
* print exception data to console output
* add exception data to the General log
* fix logging config
---
.../Listener/Commands/ListenCommand.php | 19 +++++-----
.../Listener/Commands/Log/General.php | 36 +++++++++++--------
.../Listener/Commands/Log/Output.php | 7 ++--
src/RabbitEvents/Listener/README.md | 22 +++++++-----
4 files changed, 48 insertions(+), 36 deletions(-)
diff --git a/src/RabbitEvents/Listener/Commands/ListenCommand.php b/src/RabbitEvents/Listener/Commands/ListenCommand.php
index 0b0291e..ec17afd 100644
--- a/src/RabbitEvents/Listener/Commands/ListenCommand.php
+++ b/src/RabbitEvents/Listener/Commands/ListenCommand.php
@@ -60,8 +60,7 @@ public function handle(Context $context, Worker $worker)
{
$options = $this->gatherProcessingOptions();
- $this->registerLogWriters($options->connectionName);
-
+ $this->registerLogWriters();
$this->listenForEvents();
$queue = $context->makeQueue(
@@ -123,30 +122,28 @@ protected function listenForEvents(): void
/**
* Register classes to write log output
- *
- * @param string $connectionName
*/
- protected function registerLogWriters(string $connectionName): void
+ protected function registerLogWriters(): void
{
if (!$this->option('quiet')) {
$this->logWriters[] = new Log\Output($this->laravel, $this->output);
}
- [$enabled, $defaultLoglevel, $channel] = $this->parseLoggingConfiguration($connectionName);
+ [$enabled, $defaultLoglevel, $channel] = $this->parseLoggingConfiguration();
if ($enabled) {
$this->logWriters[] = new Log\General($this->laravel, $defaultLoglevel, $channel);
}
}
- private function parseLoggingConfiguration(string $connectionName): array
+ private function parseLoggingConfiguration(): array
{
- $config = $this->laravel['config']->get('rabbitevents.connections');
+ $config = $this->laravel['config']->get('rabbitevents');
return [
- Arr::get($config, "$connectionName.logging.enabled", false),
- Arr::get($config, "$connectionName.logging.level", 'info'),
- Arr::get($config, "$connectionName.logging.channel"),
+ Arr::get($config, 'logging.enabled', false),
+ Arr::get($config, 'logging.level', 'info'),
+ Arr::get($config, 'logging.channel'),
];
}
diff --git a/src/RabbitEvents/Listener/Commands/Log/General.php b/src/RabbitEvents/Listener/Commands/Log/General.php
index 96c1156..6d40e7e 100644
--- a/src/RabbitEvents/Listener/Commands/Log/General.php
+++ b/src/RabbitEvents/Listener/Commands/Log/General.php
@@ -5,7 +5,7 @@
namespace RabbitEvents\Listener\Commands\Log;
use Illuminate\Contracts\Container\Container;
-use RabbitEvents\Listener\Message\Handler;
+use RabbitEvents\Listener\Events\ListenerHandlerExceptionOccurred;
class General extends Writer
{
@@ -23,25 +23,31 @@ public function log($event): void
{
$status = $this->getStatus($event);
- $this->write($event->handler, $status);
- }
-
- protected function write(Handler $handler, string $status): void
- {
$this->app['log']->channel($this->channel)->log(
$this->getLogLevel($status),
- sprintf('Handler "%s" %s', $handler->getName(), $status),
- [
- 'handler' => [
- 'name' => $handler->getName(),
- 'attempts' => $handler->attempts(),
- 'payload' => $handler->payload(),
- ],
- 'status' => $status,
- ]
+ sprintf('Handler "%s" %s', $event->handler->getName(), $status),
+ $this->getPayload($event, $status),
);
}
+ protected function getPayload($event, string $status): array
+ {
+ $payload = [
+ 'handler' => [
+ 'name' => $event->handler->getName(),
+ 'attempts' => $event->handler->attempts(),
+ 'payload' => $event->handler->payload(),
+ ],
+ 'status' => $status,
+ ];
+
+ if ($event instanceof ListenerHandlerExceptionOccurred) {
+ $payload['exception'] = $event->exception;
+ }
+
+ return $payload;
+ }
+
protected function getLogLevel(string $status): string
{
if (in_array($status, [static::STATUS_EXCEPTION, static::STATUS_FAILED])) {
diff --git a/src/RabbitEvents/Listener/Commands/Log/Output.php b/src/RabbitEvents/Listener/Commands/Log/Output.php
index fc3a2cb..8c5b927 100644
--- a/src/RabbitEvents/Listener/Commands/Log/Output.php
+++ b/src/RabbitEvents/Listener/Commands/Log/Output.php
@@ -7,7 +7,9 @@
use Illuminate\Console\OutputStyle;
use Illuminate\Contracts\Container\Container;
use Illuminate\Support\Carbon;
+use RabbitEvents\Listener\Events\ListenerHandlerExceptionOccurred;
use RabbitEvents\Listener\Message\Handler;
+use Symfony\Component\Console\Application as ConsoleApplication;
class Output extends Writer
{
@@ -23,8 +25,9 @@ public function log($event): void
$status = $this->getStatus($event);
$this->writeStatus($event->handler, $status, $this->getType($status));
- if (isset($event->exception)) {
- $this->output->writeln('Exception message: ' . $event->exception->getMessage());
+
+ if ($event instanceof ListenerHandlerExceptionOccurred) {
+ (new ConsoleApplication())->renderThrowable($event->exception, $this->output);
}
}
diff --git a/src/RabbitEvents/Listener/README.md b/src/RabbitEvents/Listener/README.md
index 6d0e8cd..16f2919 100644
--- a/src/RabbitEvents/Listener/README.md
+++ b/src/RabbitEvents/Listener/README.md
@@ -11,7 +11,7 @@ If you need just to handle events, you could use the RabbitEvents `Listener` sep
1. [Middleware](#listener-middleware)
1. [Stopping The Propagation Of An Event](#stopping-propagination)
1. [Console commands](#commands)
-1. [Logging](#ligging)
+1. [Logging](#logging)
## Installation via Composer
RabbitEvents Listener may be installed via the Composer package manager:
@@ -203,12 +203,16 @@ You could start listening to an event only by using `rabbitevents:listen` comman
If your listener crashes, then managers will rerun your listener and all messages sent to a queue will be handled in the same order as they were sent. There is the known problem: as queues are separated and you have messages that affect the same entity there's no guarantee that all actions will be done in an expected order. To avoid such problems you can send message time as a part of the payload and handle it internally in your listeners.
### Options
-- **--service=**. When a queue starts the name of the service becomes a part of a queue name: `service:event.name`. By default, service is the APP_NAME from your `.env`. You could override the first part of a queue name by this option.
-- **--memory=128**. The memory limit in megabytes. The RabbitEvents have restarting a worker if limit exceeded.
-- **--timeout=60**. The length of time (in seconds) each Message should be allowed to be handled.
-- **--tries=1**. Number of times to attempt to handle a Message before logging it failed.
-- **--sleep=5**. Sleep time in seconds before handling failed message next time.
-- **--quiet**. No console output
+
+| Option | Default value | Description |
+|--------------|--------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `--service=` | result of `config('app.name')` | When a queue starts the name of the service becomes a part of a queue name: `service:event.name`. You could override the first part of a queue name by this option. |
+| `--memory=` | `128` | The memory limit in megabytes. The RabbitEvents have restarting a worker if limit exceeded. |
+| `--timeout=` | `60` | The length of time (in seconds) each Message should be allowed to be handled. |
+| `--tries=` | `1` | Number of times to attempt to handle a Message before logging it failed. |
+| `--sleep=` | `5` | Sleep time in seconds before handling failed message next time. |
+| `--quiet` | disabled | No console output. |
+| `-v` | disabled | Verbosity. Enables stack trace for exceptions. |
## Command `rabbitevents:list`
@@ -223,7 +227,9 @@ The suprvisor configuration is similar to [Laravel Queue](https://laravel.com/do
# Logging
-The package provides 2 ways to see what happens to your listener. By default, it writes `processing`, `processed`, and `failed` messages to `/php/stdout`. The message includes service, event, and listener name. If you want to turn this feature off, just run listener with the `--quiet` option.
+The package provides 2 ways to see what happens to your listener. By default, it writes `processing`, `processed`, `failed` messages and occurred exceptions to console output.
+The message includes service, event, and listener name. To get exception's trace run listener with verbosity >= 1, for example `-v`.
+If you want to turn this feature off, just run listener with the `--quiet` option.
The package also supports your application logger. To use it set config value `rabbitevents.logging.enabled` to `true` and choose log level.