8000 Flush loggers on kernel.reset by dnna · Pull Request #279 · symfony/monolog-bundle · GitHub
[go: up one dir, main page]

Skip to content

Flush loggers on kernel.reset #279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ matrix:
- php: 7.0
- php: 7.1
- php: 7.2
- php: 7.3
# Test against dev versions
- php: nightly
env: DEPENDENCIES=dev
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 3.3.2 (2018-12-29)

* Fixed psr-3 processing being applied to all handlers, only leaf ones are now processing
* Fixed regression when `app` channel is defined explicitly
* Fixed handlers marked as nested not being ignored properly from the stack

## 3.3.1 (2018-11-04)

* Fixed compatiblity with Symfony 4.2

## 3.3.0 (2018-06-04)

* Fixed the autowiring of the channel logger in autoconfigured services
Expand Down
3 changes: 3 additions & 0 deletions DependencyInjection/Compiler/LoggerChannelPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public function process(ContainerBuilder $container)

// create additional channels
foreach ($container->getParameter('monolog.additional_channels') as $chan) {
if ($chan === 'app') {
continue;
}
$loggerId = sprintf('monolog.logger.%s', $chan);
$this->createLogger($chan, $loggerId, $container);
$container->getDefinition($loggerId)->setPublic(true);
Expand Down
12 changes: 9 additions & 3 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@
* - [level]: level name or int value, defaults to DEBUG
* - [bubble]: bool, defaults to true
*
* All handlers can also be marked with `nested: true` to make sure they are never added explicitly to the stack
*
* @author Jordi Boggiano <j.boggiano@seld.be>
* @author Christophe Coevoet <stof@notk.org>
*/
Expand All @@ -305,8 +307,8 @@ class Configuration implements ConfigurationInterface
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('monolog');
$treeBuilder = new TreeBuilder('monolog');
$rootNode = method_exists(TreeBuilder::class, 'getRootNode') ? $treeBuilder->getRootNode() : $treeBuilder->root('monolog');

$rootNode
->fixXmlConfig('channel')
Expand Down Expand Up @@ -342,7 +344,7 @@ public function getConfigTreeBuilder()
->booleanNode('bubble')->defaultTrue()->end()
->scalarNode('app_name')->defaultNull()->end()
->booleanNode('include_stacktraces')->defaultFalse()->end()
->booleanNode('process_psr_3_messages')->defaultTrue()->end()
->booleanNode('process_psr_3_messages')->defaultNull()->end()
->scalarNode('path')->defaultValue('%kernel.logs_dir%/%kernel.environment%.log')->end() // stream and rotating
->scalarNode('file_permission') // stream and rotating
->defaultNull()
Expand Down Expand Up @@ -708,6 +710,10 @@ public function getConfigTreeBuilder()
->ifTrue(function ($v) { return 'fingers_crossed' === $v['type'] && !empty($v['excluded_http_codes']) && !empty($v['excluded_404s']); })
->thenInvalid('You can not use excluded_http_codes together with excluded_404s in a FingersCrossedHandler')
->end()
->validate()
->ifTrue(function ($v) { return 'fingers_crossed' !== $v['type'] && (!empty($v['excluded_http_codes']) || !empty($v['excluded_404s'])); })
->thenInvalid('You can only use excluded_http_codes/excluded_404s with a FingersCrossedHandler definition')
->end()
->validate()
->ifTrue(function ($v) { return 'filter' === $v['type'] && "DEBUG" !== $v['min_level'] && !empty($v['accepted_levels']); })
->thenInvalid('You can not use min_level together with accepted_levels in a FilterHandler')
Expand Down
24 changes: 22 additions & 2 deletions DependencyInjection/MonologExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Monolog\ResettableInterface;

/**
* MonologExtension is an extension for the Monolog library.
Expand Down Expand Up @@ -131,17 +132,26 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
if ('service' === $handler['type']) {
$container->setAlias($handlerId, $handler['id']);

if (!empty($handler['nested']) && true === $handler['nested']) {
$this->markNestedHandler($handlerId);
}

return $handlerId;
}

$definition = new Definition($this->getHandlerClassByType($handler['type']));
$handlerClass = $this->getHandlerClassByType($handler['type']);
$definition = new Definition($handlerClass);

$handler['level'] = $this->levelToMonologConst($handler['level']);

if ($handler['include_stacktraces']) {
$definition->setConfigurator(array('Symfony\\Bundle\\MonologBundle\\MonologBundle', 'includeStacktraces'));
}

if (null === $handler['process_psr_3_messages']) {
$handler['process_psr_3_messages'] = !isset($handler['handler']) && !$handler['members'];
}

if ($handler['process_psr_3_messages']) {
$processorId = 'monolog.processor.psr_log_message';
if (!$container->hasDefinition($processorId)) {
Expand Down Expand Up @@ -718,7 +728,12 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
break;

default:
throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"', $handler['type'], $name));
$nullWarning = '';
if ($handler['type'] == '') {
629A $nullWarning = ', if you meant to define a null handler in a yaml config, make sure you quote "null" so it does not get converted to a php null';
}

throw new \InvalidArgumentException(sprintf('Invalid handler type "%s" given for handler "%s"' . $nullWarning, $handler['type'], $name));
}

if (!empty($handler['nested']) && true === $handler['nested']) {
Expand All @@ -728,6 +743,11 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler
if (!empty($handler['formatter'])) {
$definition->addMethodCall('setFormatter', array(new Reference($handler['formatter'])));
}

if (!in_array($handlerId, $this->nestedHandlers) && is_subclass_of($handlerClass, ResettableInterface::class)) {
$definition->addTag('kernel.reset', array('method' => 'reset'));
}

$container->setDefinition($handlerId, $definition);

return $handlerId;
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2004-2012 Fabien Potencier
Copyright (c) 2004-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
11 changes: 11 additions & 0 deletions Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ public function testTagNotBreakingIfNoLogger()
$this->assertEquals(array(), $dummyService->getArguments());
}

public function testChannelsConfigurationOptionSupportsAppChannel()
{
$container = $this->getFunctionalContainer();

$container->setParameter('monolog.additional_channels', array('app'));
$container->compile();
}

private function getContainer()
{
$container = new ContainerBuilder();
Expand Down Expand Up @@ -202,6 +210,9 @@ private function getContainerWithSetter()
return $container;
}

/**
* @return ContainerBuilder
*/
private function getFunctionalContainer()
{
$container = new ContainerBuilder();
Expand Down
2 changes: 1 addition & 1 deletion Tests/DependencyInjection/FixtureMonologExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public function testPsr3MessageProcessingEnabled()

$methodCalls = $logger->getMethodCalls();

$this->assertContains(array('pushProcessor', array(new Reference('monolog.processor.psr_log_message'))), $methodCalls, 'The PSR-3 processor should not be enabled', false, false);
$this->assertContains(array('pushProcessor', array(new Reference('monolog.processor.psr_log_message'))), $methodCalls, 'The PSR-3 processor should be enabled', false, false);
}

public function testPsr3MessageProcessingDisabled()
Expand Down
25 changes: 25 additions & 0 deletions Tests/DependencyInjection/MonologExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,31 @@ public function testLoadWithServiceHandler()
$this->assertTrue($container->hasDefinition('monolog.logger'));
$this->assertTrue($container->hasAlias('monolog.handler.custom'));

$logger = $container->getDefinition('monolog.logger');
// Custom service handler must be pushed to logger
$this->assertDICDefinitionMethodCallAt(0, $logger, 'useMicrosecondTimestamps', array('%monolog.use_microseconds%'));
$this->assertDICDefinitionMethodCallAt(1, $logger, 'pushHandler', array(new Reference('monolog.handler.custom')));

$handler = $container->findDefinition('monolog.handler.custom');
$this->assertDICDefinitionClass($handler, 'stdClass');
$this->assertDICConstructorArguments($handler, array('foo', false));
}

public function testLoadWithNestedServiceHandler()
{
$container = $this->getContainer(
array(array('handlers' => array('custom' => array('type' => 'service', 'id' => 'some.service.id', 'nested' => true)))),
array('some.service.id' => new Definition('stdClass', array('foo', false)))
);

$this->assertTrue($container->hasDefinition('monolog.logger'));
$this->assertTrue($container->hasAlias('monolog.handler.custom'));

$logger = $container->getDefinition('monolog.logger');
// Nested service handler must not be pushed to logger
$this->assertCount(1, $logger->getMethodCalls());
$this->assertDICDefinitionMethodCallAt(0, $logger, 'useMicrosecondTimestamps', array('%monolog.use_microseconds%'));

$handler = $container->findDefinition('monolog.handler.custom');
$this->assertDICDefinitionClass($handler, 'stdClass');
$this->assertDICConstructorArguments($handler, array('foo', false));
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"require-dev": {
"symfony/yaml": "~2.7|~3.3|~4.0",
"symfony/console": "~2.7|~3.3|~4.0",
"symfony/phpunit-bridge": "^3.3|^4.0"
"symfony/phpunit-bridge": "^3.4.19|^4.0"
},
"autoload": {
"psr-4": { "Symfony\\Bundle\\MonologBundle\\": "" },
Expand Down
0