Skip to content

Commit

Permalink
Log the bus name, receiver name and message class name when using Sym…
Browse files Browse the repository at this point in the history
…fony Messenger (#492)

Co-authored-by: Stefano Arlandini <[email protected]>
  • Loading branch information
airoude and ste93cry authored Jul 28, 2021
1 parent 471b9e2 commit 070486e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- Log the bus name, receiver name and message class name as event tags when using Symfony Messenger (#492)
- Make the transport factory configurable in the bundle's config (#504)
- Add the `sentry_trace_meta()` Twig function to print the `sentry-trace` HTML meta tag (#510)
- Make the list of commands for which distributed tracing is active configurable (#515)
Expand Down
30 changes: 23 additions & 7 deletions src/EventListener/MessengerListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace Sentry\SentryBundle\EventListener;

use Sentry\Event;
use Sentry\State\HubInterface;
use Sentry\State\Scope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\Stamp\BusNameStamp;

final class MessengerListener
{
Expand Down Expand Up @@ -45,15 +48,28 @@ public function handleWorkerMessageFailedEvent(WorkerMessageFailedEvent $event):
return;
}

$error = $event->getThrowable();
$this->hub->withScope(function (Scope $scope) use ($event): void {
$envelope = $event->getEnvelope();
$exception = $event->getThrowable();

if ($error instanceof HandlerFailedException) {
foreach ($error->getNestedExceptions() as $nestedException) {
$this->hub->captureException($nestedException);
$scope->setTag('messenger.receiver_name', $event->getReceiverName());
$scope->setTag('messenger.message_class', \get_class($envelope->getMessage()));

/** @var BusNameStamp|null $messageBusStamp */
$messageBusStamp = $envelope->last(BusNameStamp::class);

if (null !== $messageBusStamp) {
$scope->setTag('messenger.message_bus', $messageBusStamp->getBusName());
}
} else {
$this->hub->captureException($error);
}

if ($exception instanceof HandlerFailedException) {
foreach ($exception->getNestedExceptions() as $nestedException) {
$this->hub->captureException($nestedException);
}
} else {
$this->hub->captureException($exception);
}
});

$this->flushClient();
}
Expand Down
46 changes: 39 additions & 7 deletions tests/EventListener/MessengerListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Sentry\ClientInterface;
use Sentry\Event;
use Sentry\SentryBundle\EventListener\MessengerListener;
use Sentry\SentryBundle\Tests\End2End\App\Kernel;
use Sentry\State\HubInterface;
use Sentry\State\Scope;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\BusNameStamp;

final class MessengerListenerTest extends TestCase
{
Expand All @@ -37,14 +40,23 @@ protected function setUp(): void
/**
* @dataProvider handleWorkerMessageFailedEventDataProvider
*
* @param \Throwable[] $exceptions
* @param \Throwable[] $exceptions
* @param array<string, string> $expectedTags
*/
public function testHandleWorkerMessageFailedEvent(array $exceptions, WorkerMessageFailedEvent $event): void
public function testHandleWorkerMessageFailedEvent(array $exceptions, WorkerMessageFailedEvent $event, array $expectedTags): void
{
if (!$this->supportsMessenger()) {
$this->markTestSkipped('Messenger not supported in this environment.');
}

$scope = new Scope();

$this->hub->expects($this->once())
->method('withScope')
->willReturnCallback(function (callable $callback) use ($scope): void {
$callback($scope);
});

$this->hub->expects($this->exactly(\count($exceptions)))
->method('captureException')
->withConsecutive(...array_map(static function (\Throwable $exception): array {
Expand All @@ -57,6 +69,10 @@ public function testHandleWorkerMessageFailedEvent(array $exceptions, WorkerMess

$listener = new MessengerListener($this->hub);
$listener->handleWorkerMessageFailedEvent($event);

$sentryEvent = $scope->applyToEvent(Event::createEvent());

$this->assertSame($expectedTags, $sentryEvent->getTags());
}

/**
Expand All @@ -74,18 +90,34 @@ public function handleWorkerMessageFailedEventDataProvider(): \Generator
new \Exception(),
];

yield [
yield 'envelope.throwable INSTANCEOF HandlerFailedException' => [
$exceptions,
$this->getMessageFailedEvent($envelope, 'receiver', new HandlerFailedException($envelope, $exceptions), false),
[
'messenger.receiver_name' => 'receiver',
'messenger.message_class' => \get_class($envelope->getMessage()),
],
];

$exceptions = [
new \Exception(),
yield 'envelope.throwable INSTANCEOF Exception' => [
[$exceptions[0]],
$this->getMessageFailedEvent($envelope, 'receiver', $exceptions[0], false),
[
'messenger.receiver_name' => 'receiver',
'messenger.message_class' => \get_class($envelope->getMessage()),
],
];

yield [
$exceptions,
$envelope = new Envelope((object) [], [new BusNameStamp('bus.foo')]);

yield 'envelope.stamps CONTAINS BusNameStamp' => [
[$exceptions[0]],
$this->getMessageFailedEvent($envelope, 'receiver', $exceptions[0], false),
[
'messenger.receiver_name' => 'receiver',
'messenger.message_class' => \get_class($envelope->getMessage()),
'messenger.message_bus' => 'bus.foo',
],
];
}

Expand Down

0 comments on commit 070486e

Please sign in to comment.