Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
ste93cry committed Aug 11, 2021
2 parents c5caac2 + 1bffee8 commit 3b9c271
Show file tree
Hide file tree
Showing 37 changed files with 530 additions and 119 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

## 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)
- Introduce `TracingDriverConnection::getWrappedConnection()` (#536)
- Add the `logger` config option to ease setting a PSR-3 logger to debug the SDK (#538)
- Bump requirement for DBAL tracing to `^2.13|^3`; simplify the DBAL tracing feature (#527)

## 4.1.4 (2021-06-18)

- Fix decoration of cache adapters inheriting parent service (#525)
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"symfony/security-core": "^3.4.44||^4.4.20||^5.0.11"
},
"require-dev": {
"doctrine/dbal": "^2.10||^3.0",
"doctrine/dbal": "^2.13||^3.0",
"doctrine/doctrine-bundle": "^1.12||^2.0",
"friendsofphp/php-cs-fixer": "^2.18",
"jangregor/phpstan-prophecy": "^0.8",
Expand Down Expand Up @@ -91,7 +91,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "4.x-dev",
"dev-master": "4.2.x-dev",
"releases/3.2.x": "3.2.x-dev",
"releases/2.x": "2.x-dev",
"releases/1.x": "1.x-dev"
Expand Down
24 changes: 22 additions & 2 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ parameters:
path: src/Tracing/Doctrine/DBAL/TracingDriver.php

-
message: "#^Parameter \\#2 \\$query of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Query\\|null, Doctrine\\\\DBAL\\\\Driver\\\\Exception given\\.$#"
message: "#^Parameter \\#2 \\$query of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Query\\|null, Doctrine\\\\DBAL\\\\Driver\\\\DriverException given\\.$#"
count: 1
path: src/Tracing/Doctrine/DBAL/TracingDriver.php

-
message: "#^Parameter \\$exception of method Sentry\\\\SentryBundle\\\\Tracing\\\\Doctrine\\\\DBAL\\\\TracingDriver\\:\\:convertException\\(\\) has invalid typehint type Doctrine\\\\DBAL\\\\Driver\\\\DriverException\\.$#"
count: 1
path: src/Tracing/Doctrine/DBAL/TracingDriver.php

Expand Down Expand Up @@ -115,6 +120,11 @@ parameters:
count: 1
path: src/aliases.php

-
message: "#^Class Symfony\\\\Bundle\\\\FrameworkBundle\\\\Client not found\\.$#"
count: 1
path: tests/End2End/TracingEnd2EndTest.php

-
message: "#^Call to method getException\\(\\) on an unknown class Symfony\\\\Component\\\\HttpKernel\\\\Event\\\\GetResponseForExceptionEvent\\.$#"
count: 1
Expand Down Expand Up @@ -235,13 +245,23 @@ parameters:
count: 1
path: tests/Tracing/Cache/AbstractTraceableCacheAdapterTest.php

-
message: "#^Class Doctrine\\\\DBAL\\\\Driver\\\\DriverException not found\\.$#"
count: 3
path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php

-
message: "#^Parameter \\#1 \\$driverException of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Driver\\\\Exception, string given\\.$#"
count: 1
path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php

-
message: "#^Parameter \\#2 \\$query of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Query\\|null, Doctrine\\\\DBAL\\\\Driver\\\\Exception&PHPUnit\\\\Framework\\\\MockObject\\\\MockObject given\\.$#"
message: "#^Parameter \\#1 \\$originalClassName of method PHPUnit\\\\Framework\\\\TestCase\\:\\:createMock\\(\\) expects class\\-string\\<Doctrine\\\\DBAL\\\\Driver\\\\DriverException\\>, string given\\.$#"
count: 2
path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php

-
message: "#^Parameter \\#2 \\$query of class Doctrine\\\\DBAL\\\\Exception\\\\DriverException constructor expects Doctrine\\\\DBAL\\\\Query\\|null, Doctrine\\\\DBAL\\\\Driver\\\\DriverException&PHPUnit\\\\Framework\\\\MockObject\\\\MockObject given\\.$#"
count: 1
path: tests/Tracing/Doctrine/DBAL/TracingDriverTest.php

Expand Down
7 changes: 1 addition & 6 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.7.0@d4377c0baf3ffbf0b1ec6998e8d1be2a40971005">
<files psalm-version="4.8.1@f73f2299dbc59a3e6c4d66cff4605176e728ee69">
<file src="src/EventListener/ConsoleCommandListener.php">
<InvalidExtendClass occurrences="1">
<code>ConsoleListener</code>
Expand All @@ -8,9 +8,4 @@
<code>public function __construct(HubInterface $hub, bool $captureErrors = true)</code>
</MethodSignatureMismatch>
</file>
<file src="src/Tracing/Cache/TraceableCacheAdapterTrait.php">
<InvalidReturnType occurrences="1">
<code>getItems</code>
</InvalidReturnType>
</file>
</files>
18 changes: 18 additions & 0 deletions src/DependencyInjection/Compiler/DbalTracingPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Sentry\SentryBundle\DependencyInjection\Compiler;

use Doctrine\DBAL\Driver\ResultStatement;
use Doctrine\DBAL\Result;
use Sentry\SentryBundle\Tracing\Doctrine\DBAL\ConnectionConfigurator;
use Sentry\SentryBundle\Tracing\Doctrine\DBAL\TracingDriverMiddleware;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
Expand Down Expand Up @@ -39,6 +40,8 @@ public function process(ContainerBuilder $container): void
return;
}

$this->assertRequiredDbalVersion();

/** @var string[] $connectionsToTrace */
$connectionsToTrace = $container->getParameter('sentry.tracing.dbal.connections');

Expand Down Expand Up @@ -92,4 +95,19 @@ private function getSetMiddlewaresMethodCallArguments(Definition $definition): a

return [];
}

private function assertRequiredDbalVersion(): void
{
if (interface_exists(Result::class)) {
// DBAL ^2.13
return;
}

if (class_exists(Result::class)) {
// DBAL ^3
return;
}

throw new \LogicException('Tracing support cannot be enabled as the Doctrine DBAL 2.13+ package is not installed. Try running "composer require doctrine/dbal:^2.13".');
}
}
19 changes: 19 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Jean85\PrettyVersions;
use Sentry\Options;
use Sentry\SentryBundle\ErrorTypesParser;
use Sentry\Transport\TransportFactoryInterface;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
Expand Down Expand Up @@ -35,6 +36,14 @@ public function getConfigTreeBuilder(): TreeBuilder
->info('If this value is not provided, the SDK will try to read it from the SENTRY_DSN environment variable. If that variable also does not exist, the SDK will just not send any events.')
->end()
->booleanNode('register_error_listener')->defaultTrue()->end()
->scalarNode('logger')
->info('The service ID of the PSR-3 logger used to log messages coming from the SDK client. Be aware that setting the same logger of the application may create a circular loop when an event fails to be sent.')
->defaultNull()
->end()
->scalarNode('transport_factory')
->info('The service ID of the transport factory used by the default SDK client.')
->defaultValue(TransportFactoryInterface::class)
->end()
->arrayNode('options')
->addDefaultsIfNotSet()
->fixXmlConfig('integration')
Expand Down Expand Up @@ -167,6 +176,16 @@ private function addDistributedTracingSection(ArrayNodeDefinition $rootNode): vo
->arrayNode('cache')
->{class_exists(CacheItem::class) ? 'canBeDisabled' : 'canBeEnabled'}()
->end()
->arrayNode('console')
->addDefaultsIfNotSet()
->fixXmlConfig('excluded_command')
->children()
->arrayNode('excluded_commands')
->scalarPrototype()->end()
->defaultValue(['messenger:consume'])
->end()
->end()
->end()
->end()
->end()
->end();
Expand Down
11 changes: 8 additions & 3 deletions src/DependencyInjection/SentryExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Jean85\PrettyVersions;
use LogicException;
use Psr\Log\NullLogger;
use Sentry\Client;
use Sentry\ClientBuilder;
use Sentry\Integration\IgnoreErrorsIntegration;
Expand All @@ -26,7 +27,6 @@
use Sentry\SentryBundle\Tracing\Twig\TwigTracingExtension;
use Sentry\Serializer\RepresentationSerializer;
use Sentry\Serializer\Serializer;
use Sentry\Transport\TransportFactoryInterface;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Config\FileLocator;
Expand Down Expand Up @@ -128,9 +128,10 @@ private function registerConfiguration(ContainerBuilder $container, array $confi
->setArgument(0, new Reference('sentry.client.options'))
->addMethodCall('setSdkIdentifier', [SentryBundle::SDK_IDENTIFIER])
->addMethodCall('setSdkVersion', [PrettyVersions::getVersion('sentry/sentry-symfony')->getPrettyVersion()])
->addMethodCall('setTransportFactory', [new Reference(TransportFactoryInterface::class)])
->addMethodCall('setTransportFactory', [new Reference($config['transport_factory'])])
->addMethodCall('setSerializer', [$serializer])
->addMethodCall('setRepresentationSerializer', [$representationSerializerDefinition]);
->addMethodCall('setRepresentationSerializer', [$representationSerializerDefinition])
->addMethodCall('setLogger', [null !== $config['logger'] ? new Reference($config['logger']) : new Reference(NullLogger::class, ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)]);

$container
->setDefinition('sentry.client', new Definition(Client::class))
Expand Down Expand Up @@ -175,7 +176,11 @@ private function registerTracingConfiguration(ContainerBuilder $container, array
$container->removeDefinition(TracingRequestListener::class);
$container->removeDefinition(TracingSubRequestListener::class);
$container->removeDefinition(TracingConsoleListener::class);

return;
}

$container->getDefinition(TracingConsoleListener::class)->replaceArgument(1, $config['console']['excluded_commands']);
}

/**
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
34 changes: 30 additions & 4 deletions src/EventListener/TracingConsoleListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@ final class TracingConsoleListener
*/
private $hub;

/**
* @var string[] The list of commands for which distributed tracing must be skipped
*/
private $excludedCommands;

/**
* Constructor.
*
* @param HubInterface $hub The current hub
* @param HubInterface $hub The current hub
* @param string[] $excludedCommands The list of commands for which distributed tracing must be skipped
*/
public function __construct(HubInterface $hub)
public function __construct(HubInterface $hub, array $excludedCommands = [])
{
$this->hub = $hub;
$this->excludedCommands = $excludedCommands;
}

/**
Expand All @@ -42,18 +49,24 @@ public function __construct(HubInterface $hub)
*/
public function handleConsoleCommandEvent(ConsoleCommandEvent $event): void
{
$command = $event->getCommand();

if ($this->isCommandExcluded($command)) {
return;
}

$currentSpan = $this->hub->getSpan();

if (null === $currentSpan) {
$transactionContext = new TransactionContext();
$transactionContext->setOp('console.command');
$transactionContext->setName($this->getSpanName($event->getCommand()));
$transactionContext->setName($this->getSpanName($command));

$span = $this->hub->startTransaction($transactionContext);
} else {
$spanContext = new SpanContext();
$spanContext->setOp('console.command');
$spanContext->setDescription($this->getSpanName($event->getCommand()));
$spanContext->setDescription($this->getSpanName($command));

$span = $currentSpan->startChild($spanContext);
}
Expand All @@ -69,6 +82,10 @@ public function handleConsoleCommandEvent(ConsoleCommandEvent $event): void
*/
public function handleConsoleTerminateEvent(ConsoleTerminateEvent $event): void
{
if ($this->isCommandExcluded($event->getCommand())) {
return;
}

$span = $this->hub->getSpan();

if (null !== $span) {
Expand All @@ -84,4 +101,13 @@ private function getSpanName(?Command $command): string

return $command->getName();
}

private function isCommandExcluded(?Command $command): bool
{
if (null === $command) {
return true;
}

return \in_array($command->getName(), $this->excludedCommands, true);
}
}
9 changes: 9 additions & 0 deletions src/Resources/config/schema/sentry-1.0.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
</xsd:choice>

<xsd:attribute name="register-error-listener" type="xsd:boolean" />
<xsd:attribute name="transport-factory" type="xsd:string" />
<xsd:attribute name="dsn" type="xsd:string" />
<xsd:attribute name="logger" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="options">
Expand Down Expand Up @@ -86,6 +88,7 @@
<xsd:element name="dbal" type="tracing-dbal" minOccurs="0" maxOccurs="1" />
<xsd:element name="twig" type="tracing-twig" minOccurs="0" maxOccurs="1" />
<xsd:element name="cache" type="tracing-cache" minOccurs="0" maxOccurs="1" />
<xsd:element name="console" type="tracing-console" minOccurs="0" maxOccurs="1" />
</xsd:choice>

<xsd:attribute name="enabled" type="xsd:boolean" default="true"/>
Expand All @@ -106,4 +109,10 @@
<xsd:complexType name="tracing-cache">
<xsd:attribute name="enabled" type="xsd:boolean" />
</xsd:complexType>

<xsd:complexType name="tracing-console">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="excluded-command" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
7 changes: 7 additions & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@

<service id="Sentry\SentryBundle\EventListener\TracingConsoleListener" class="Sentry\SentryBundle\EventListener\TracingConsoleListener">
<argument type="service" id="Sentry\State\HubInterface" />
<argument /> <!-- $excludedCommands -->

<tag name="kernel.event_listener" event="console.command" method="handleConsoleCommandEvent" priority="118" />
<tag name="kernel.event_listener" event="console.terminate" method="handleConsoleTerminateEvent" priority="-54" />
Expand Down Expand Up @@ -116,5 +117,11 @@
<argument type="service" id="Symfony\Component\HttpFoundation\RequestStack" />
<argument type="service" id="Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface" on-invalid="null" />
</service>

<service id="Sentry\SentryBundle\Twig\SentryExtension" class="Sentry\SentryBundle\Twig\SentryExtension">
<argument type="service" id="Sentry\State\HubInterface" />

<tag name="twig.extension" />
</service>
</services>
</container>
Loading

0 comments on commit 3b9c271

Please sign in to comment.