Skip to content

Commit cba8329

Browse files
authored
Merge pull request #247 from HypeMC/disable-error-listener
Options to disable error listener and/or enable Monolog handler
2 parents aa7d969 + 168548c commit cba8329

File tree

8 files changed

+236
-13
lines changed

8 files changed

+236
-13
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
- Fix compatibility with sentry/sentry 2.2+ (#244)
1111
- Add support for `class_serializers` option (#245)
1212
- Add support for `max_request_body_size` option (#249)
13+
- Add option to disable the error listener completely (#247, thanks to @HypeMC)
14+
- Add options to register the Monolog Handler (#247, thanks to @HypeMC)
1315

1416
## 3.1.0 - 2019-07-02
1517
- Add support for Symfony 2.8 (#233, thanks to @nocive)

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,20 @@ the [PHP specific](https://docs.sentry.io/platforms/php/#php-specific-options) o
103103
#### Optional: use monolog handler provided by `sentry/sentry`
104104
*Note: this step is optional*
105105

106-
If You're using `monolog` for logging e.g. in-app errors, You
106+
If you're using `monolog` for logging e.g. in-app errors, you
107107
can use this handler in order for them to show up in Sentry.
108108

109-
First, define `Sentry\Monolog\Handler` as a service in `config/services.yaml`
109+
First, enable & configure the `Sentry\Monolog\Handler`; you'll also need
110+
to disable the `Sentry\SentryBundle\EventListener\ErrorListener` to
111+
avoid having duplicate events in Sentry:
110112

111113
```yaml
112-
services:
113-
sentry.monolog.handler:
114-
class: Sentry\Monolog\Handler
115-
arguments:
116-
$level: 'error'
114+
sentry:
115+
register_error_listener: false # Disables the ErrorListener
116+
monolog:
117+
error_handler:
118+
enabled: true
119+
level: error
117120
```
118121

119122
Then enable it in `monolog` config:
@@ -123,8 +126,7 @@ monolog:
123126
handlers:
124127
sentry:
125128
type: service
126-
id: sentry.monolog.handler
127-
level: error
129+
id: Sentry\Monolog\Handler
128130
```
129131

130132
## Maintained versions

composer.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,24 @@
3232
"require-dev": {
3333
"friendsofphp/php-cs-fixer": "^2.8",
3434
"jangregor/phpstan-prophecy": "^0.3.0",
35+
"monolog/monolog": "^1.11||^2.0",
3536
"php-http/mock-client": "^1.0",
3637
"phpstan/phpstan": "^0.11",
3738
"phpstan/phpstan-phpunit": "^0.11",
3839
"phpunit/phpunit": "^7.5",
3940
"scrutinizer/ocular": "^1.4",
4041
"symfony/expression-language": "^2.8||^3.0||^4.0"
4142
},
43+
"suggest": {
44+
"monolog/monolog": "Required to use the Monolog handler"
45+
},
4246
"autoload": {
43-
"psr-4" : {
47+
"psr-4": {
4448
"Sentry\\SentryBundle\\": "src/"
4549
}
4650
},
4751
"autoload-dev": {
48-
"psr-4" : {
52+
"psr-4": {
4953
"Sentry\\SentryBundle\\Test\\": "test"
5054
}
5155
},

src/DependencyInjection/Configuration.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public function getConfigTreeBuilder(): TreeBuilder
3737
->ifString()
3838
->then($this->getTrimClosure());
3939

40+
$rootNode->children()
41+
->booleanNode('register_error_listener')
42+
->defaultTrue();
43+
4044
// Options array (to be passed to Sentry\Options constructor) -- please keep alphabetical order!
4145
$optionsNode = $rootNode->children()
4246
->arrayNode('options')
@@ -139,6 +143,24 @@ public function getConfigTreeBuilder(): TreeBuilder
139143
$listenerPriorities->scalarNode('console_error')
140144
->defaultValue(128);
141145

146+
// Monolog handler configuration
147+
$monologConfiguration = $rootNode->children()
148+
->arrayNode('monolog')
149+
->addDefaultsIfNotSet()
150+
->children();
151+
152+
$errorHandler = $monologConfiguration
153+
->arrayNode('error_handler')
154+
->addDefaultsIfNotSet()
155+
->children();
156+
$errorHandler->booleanNode('enabled')
157+
->defaultFalse();
158+
$errorHandler->scalarNode('level')
159+
->defaultValue('DEBUG')
160+
->cannotBeEmpty();
161+
$errorHandler->booleanNode('bubble')
162+
->defaultTrue();
163+
142164
return $treeBuilder;
143165
}
144166

src/DependencyInjection/SentryExtension.php

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace Sentry\SentryBundle\DependencyInjection;
44

5+
use Monolog\Logger as MonologLogger;
56
use Sentry\ClientBuilderInterface;
7+
use Sentry\Monolog\Handler;
68
use Sentry\Options;
79
use Sentry\SentryBundle\Command\SentryTestCommand;
810
use Sentry\SentryBundle\ErrorTypesParser;
@@ -14,6 +16,7 @@
1416
use Symfony\Component\Config\FileLocator;
1517
use Symfony\Component\Console\ConsoleEvents;
1618
use Symfony\Component\DependencyInjection\ContainerBuilder;
19+
use Symfony\Component\DependencyInjection\Exception\LogicException;
1720
use Symfony\Component\DependencyInjection\Loader;
1821
use Symfony\Component\DependencyInjection\Reference;
1922
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@@ -47,8 +50,9 @@ public function load(array $configs, ContainerBuilder $container): void
4750
$container->setParameter('sentry.listener_priorities.' . $key, $priority);
4851
}
4952

50-
$this->tagConsoleErrorListener($container);
53+
$this->configureErrorListener($container, $processedConfiguration);
5154
$this->setLegacyVisibilities($container);
55+
$this->configureMonologHandler($container, $processedConfiguration['monolog']);
5256
}
5357

5458
private function passConfigurationToOptions(ContainerBuilder $container, array $processedConfiguration): void
@@ -134,6 +138,17 @@ private function valueToCallable($value)
134138
return $value;
135139
}
136140

141+
private function configureErrorListener(ContainerBuilder $container, array $processedConfiguration): void
142+
{
143+
if (! $processedConfiguration['register_error_listener']) {
144+
$container->removeDefinition(ErrorListener::class);
145+
146+
return;
147+
}
148+
149+
$this->tagConsoleErrorListener($container);
150+
}
151+
137152
/**
138153
* BC layer for Symfony < 3.3; see https://symfony.com/blog/new-in-symfony-3-3-better-handling-of-command-exceptions
139154
*/
@@ -166,9 +181,40 @@ private function setLegacyVisibilities(ContainerBuilder $container): void
166181
if (Kernel::VERSION_ID < 30300) {
167182
$container->getDefinition(SentryTestCommand::class)->setPublic(true);
168183
$container->getDefinition(ConsoleListener::class)->setPublic(true);
169-
$container->getDefinition(ErrorListener::class)->setPublic(true);
170184
$container->getDefinition(RequestListener::class)->setPublic(true);
171185
$container->getDefinition(SubRequestListener::class)->setPublic(true);
186+
187+
if ($container->hasDefinition(ErrorListener::class)) {
188+
$container->getDefinition(ErrorListener::class)->setPublic(true);
189+
}
172190
}
173191
}
192+
193+
private function configureMonologHandler(ContainerBuilder $container, array $monologConfiguration): void
194+
{
195+
$errorHandler = $monologConfiguration['error_handler'];
196+
197+
if (! $errorHandler['enabled']) {
198+
$container->removeDefinition(Handler::class);
199+
200+
return;
201+
}
202+
203+
if (! class_exists(Handler::class)) {
204+
throw new LogicException(
205+
sprintf('Missing class "%s", try updating "sentry/sentry" to a newer version.', Handler::class)
206+
);
207+
}
208+
209+
if (! class_exists(MonologLogger::class)) {
210+
throw new LogicException(
211+
sprintf('You cannot use "%s" if Monolog is not available.', Handler::class)
212+
);
213+
}
214+
215+
$container
216+
->getDefinition(Handler::class)
217+
->replaceArgument('$level', MonologLogger::toMonologLevel($errorHandler['level']))
218+
->replaceArgument('$bubble', $errorHandler['bubble']);
219+
}
174220
}

src/Resources/config/services.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,11 @@
5151
<service id="Sentry\SentryBundle\Command\SentryTestCommand" class="Sentry\SentryBundle\Command\SentryTestCommand" public="false">
5252
<tag name="console.command" />
5353
</service>
54+
55+
<service id="Sentry\Monolog\Handler" class="Sentry\Monolog\Handler" public="false">
56+
<argument type="service" id="Sentry\State\HubInterface" />
57+
<argument key="$level" />
58+
<argument key="$bubble" />
59+
</service>
5460
</services>
5561
</container>

test/DependencyInjection/ConfigurationTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public function testConfigurationDefaults(): void
4848
$processed = $this->processConfiguration([]);
4949
$expectedDefaults = [
5050
'dsn' => null,
51+
'register_error_listener' => true,
5152
'listener_priorities' => [
5253
'request' => 1,
5354
'sub_request' => 1,
@@ -67,6 +68,13 @@ public function testConfigurationDefaults(): void
6768
'project_root' => '%kernel.root_dir%/..',
6869
'tags' => [],
6970
],
71+
'monolog' => [
72+
'error_handler' => [
73+
'enabled' => false,
74+
'level' => 'DEBUG',
75+
'bubble' => true,
76+
],
77+
],
7078
];
7179

7280
if (method_exists(Kernel::class, 'getProjectDir')) {

0 commit comments

Comments
 (0)