Skip to content

Commit 11821b7

Browse files
committed
feature #313 #310 : Add sentry 2.0 type (Taluu)
This PR was squashed before being merged into the 3.x-dev branch (closes #313). Discussion ---------- #310 : Add sentry 2.0 type As said on #310, sentry completely changed their API and even stopped calling their client "raven", using now php-http to handle the requests to their api. So this PR adds a new type in the config to support the handler they made. I'm not sure on a few points (such as the self-referencing hub, which I commented because otherwise it would go on an infinite recursion problem), and I based the service definition on [sentry's bundle](https://github.com/getsentry/sentry-symfony). Poke @Jean85 maybe, as he is maintaining (as far as I can tell ?) the current sentry bundle. Fixes #310 Commits ------- 751173a #310 : Add sentry 2.0 type
2 parents f5dd1d4 + 751173a commit 11821b7

File tree

4 files changed

+140
-5
lines changed

4 files changed

+140
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## 3.5.0 (xxxx-xx-xx)
22

3+
* Add `sentry` type to use sentry 2.0 client
4+
35
## 3.4.0 (2019-06-20)
46

57
* Deprecate "excluded_404s" option

DependencyInjection/Configuration.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,14 @@
194194
* - [timeout]: float
195195
* - [connection_timeout]: float
196196
*
197-
* - raven:
197+
* - raven / sentry:
198198
* - dsn: connection string
199199
* - client_id: Raven client custom service id (optional)
200200
* - [release]: release number of the application that will be attached to logs, defaults to null
201201
* - [level]: level name or int value, defaults to DEBUG
202202
* - [bubble]: bool, defaults to true
203203
* - [auto_log_stacks]: bool, defaults to false
204+
* - [environment]: string, default to null (no env specified)
204205
*
205206
* - newrelic:
206207
* - [level]: level name or int value, defaults to DEBUG
@@ -620,11 +621,11 @@ public function getConfigTreeBuilder()
620621
->scalarNode('store')->defaultNull()->end() // deduplication
621622
->scalarNode('connection_timeout')->end() // socket_handler, logentries, pushover, hipchat & slack
622623
->booleanNode('persistent')->end() // socket_handler
623-
->scalarNode('dsn')->end() // raven_handler
624-
->scalarNode('client_id')->defaultNull()->end() // raven_handler
624+
->scalarNode('dsn')->end() // raven_handler, sentry_handler
625+
->scalarNode('client_id')->defaultNull()->end() // raven_handler, sentry_handler
625626
->scalarNode('auto_log_stacks')->defaultFalse()->end() // raven_handler
626-
->scalarNode('release')->defaultNull()->end() // raven_handler
627-
->scalarNode('environment')->defaultNull()->end() // raven_handler
627+
->scalarNode('release')->defaultNull()->end() // raven_handler, sentry_handler
628+
->scalarNode('environment')->defaultNull()->end() // raven_handler, sentry_handler
628629
->scalarNode('message_type')->defaultValue(0)->end() // error_log
629630
->arrayNode('tags') // loggly
630631
->beforeNormalization()
@@ -837,6 +838,10 @@ public function getConfigTreeBuilder()
837838
->ifTrue(function ($v) { return 'raven' === $v['type'] && !array_key_exists('dsn', $v) && null === $v['client_id']; })
838839
->thenInvalid('The DSN has to be specified to use a RavenHandler')
839840
->end()
841+
->validate()
842+
->ifTrue(function ($v) { return 'sentry' === $v['type'] && !array_key_exists('dsn', $v) && null === $v['client_id']; })
843+
->thenInvalid('The DSN has to be specified to use Sentry\'s handler')
844+
->end()
840845
->validate()
841846
->ifTrue(function ($v) { return 'hipchat' === $v['type'] && (empty($v['token']) || empty($v['room'])); })
842847
->thenInvalid('The token and room have to be specified to use a HipChatHandler')

DependencyInjection/MonologExtension.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,51 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
668668
));
669669
break;
670670

671+
case 'sentry':
672+
if (null !== $handler['client_id']) {
673+
$clientId = $handler['client_id'];
674+
} else {
675+
$options = new Definition(
676+
'Sentry\\Options',
677+
array(array('dsn' => $handler['dsn']))
678+
);
679+
680+
if (!empty($handler['environment'])) {
681+
$options->addMethodCall('setEnvironment', [$handler['environment']]);
682+
}
683+
684+
if (!empty($handler['release'])) {
685+
$options->addMethodCall('setRelease', [$handler['release']]);
686+
}
687+
688+
$builder = new Definition('Sentry\\ClientBuilder', array($options));
689+
690+
$client = new Definition('Sentry\\Client');
691+
$client->setFactory(array($builder, 'getClient'));
692+
693+
$clientId = 'monolog.sentry.client.'.sha1($handler['dsn']);
694+
$container->setDefinition($clientId, $client);
695+
696+
if (!$container->hasAlias('Sentry\\ClientInterface')) {
697+
$container->setAlias('Sentry\\ClientInterface', $clientId);
698+
}
699+
}
700+
701+
$hub = new Definition(
702+
'Sentry\\State\\Hub',
703+
array(new Reference($clientId))
704+
);
705+
706+
// can't set the hub to the current hub, getting into a recursion otherwise...
707+
//$hub->addMethodCall('setCurrent', array($hub));
708+
709+
$definition->setArguments(array(
710+
$hub,
711+
$handler['level'],
712+
$handler['bubble'],
713+
));
714+
break;
715+
671716
case 'raven':
672717
if (null !== $handler['client_id']) {
673718
$clientId = $handler['client_id'];
@@ -854,6 +899,7 @@ private function getHandlerClassByType($handlerType)
854899
'socket' => 'Monolog\Handler\SocketHandler',
855900
'pushover' => 'Monolog\Handler\PushoverHandler',
856901
'raven' => 'Monolog\Handler\RavenHandler',
902+
'sentry' => 'Sentry\Monolog\Handler',
857903
'newrelic' => 'Monolog\Handler\NewRelicHandler',
858904
'hipchat' => 'Monolog\Handler\HipChatHandler',
859905
'slack' => 'Monolog\Handler\SlackHandler',

Tests/DependencyInjection/MonologExtensionTest.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,88 @@ public function testRavenHandlerWhenAClientIsSpecified()
342342
$this->assertDICConstructorArguments($handler, array(new Reference('raven.client'), 100, true));
343343
}
344344

345+
public function testSentryHandlerWhenConfigurationIsWrong()
346+
{
347+
try {
348+
$this->getContainer(array(array('handlers' => array('sentry' => array('type' => 'sentry')))));
349+
$this->fail();
350+
} catch (InvalidConfigurationException $e) {
351+
$this->assertContains('DSN', $e->getMessage());
352+
}
353+
}
354+
355+
public function testSentryHandlerWhenADSNIsSpecified()
356+
{
357+
$dsn = 'http://43f6017361224d098402974103bfc53d:a6a0538fc2934ba2bed32e08741b2cd3@marca.python.live.cheggnet.com:9000/1';
358+
359+
$container = $this->getContainer(array(array('handlers' => array('sentry' => array(
360+
'type' => 'sentry', 'dsn' => $dsn)
361+
))));
362+
$this->assertTrue($container->hasDefinition('monolog.logger'));
363+
$this->assertTrue($container->hasDefinition('monolog.handler.sentry'));
364+
365+
$logger = $container->getDefinition('monolog.logger');
366+
$this->assertDICDefinitionMethodCallAt(0, $logger, 'useMicrosecondTimestamps', array('%monolog.use_microseconds%'));
367+
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.sentry')));
368+
369+
$handler = $container->getDefinition('monolog.handler.sentry');
370+
$this->assertDICDefinitionClass($handler, 'Sentry\Monolog\Handler');
371+
}
372+
373+
public function testSentryHandlerWhenADSNAndAClientAreSpecified()
374+
{
375+
$container = $this->getContainer(
376+
array(
377+
array(
378+
'handlers' => array(
379+
'sentry' => array(
380+
'type' => 'sentry',
381+
'dsn' => 'foobar',
382+
'client_id' => 'sentry.client',
383+
),
384+
),
385+
),
386+
),
387+
array(
388+
'sentry.client' => new Definition('Sentry\Client'),
389+
)
390+
);
391+
392+
$logger = $container->getDefinition('monolog.logger');
393+
$this->assertDICDefinitionMethodCallAt(0, $logger, 'useMicrosecondTimestamps', array('%monolog.use_microseconds%'));
394+
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.sentry')));
395+
396+
$handler = $container->getDefinition('monolog.handler.sentry');
397+
$this->assertDICConstructorArguments($handler->getArguments()[0], array(new Reference('sentry.client')));
398+
}
399+
400+
public function testSentryHandlerWhenAClientIsSpecified()
401+
{
402+
$container = $this->getContainer(
403+
array(
404+
array(
405+
'handlers' => array(
406+
'sentry' => array(
407+
'type' =>
408+
'sentry',
409+
'client_id' => 'sentry.client',
410+
),
411+
),
412+
),
413+
),
414+
array(
415+
'sentry.client' => new Definition('Sentry\Client'),
416+
)
417+
);
418+
419+
$logger = $container->getDefinition('monolog.logger');
420+
$this->assertDICDefinitionMethodCallAt(0, $logger, 'useMicrosecondTimestamps', array('%monolog.use_microseconds%'));
421+
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.sentry')));
422+
423+
$handler = $container->getDefinition('monolog.handler.sentry');
424+
$this->assertDICConstructorArguments($handler->getArguments()[0], array(new Reference('sentry.client')));
425+
}
426+
345427
public function testLogglyHandler()
346428
{
347429
$token = '026308d8-2b63-4225-8fe9-e01294b6e472';

0 commit comments

Comments
 (0)