merged branch stof/monolog (PR #1556)
Commits -------f8b5f35
[MonologBundle] Refactored the way to configure the email prototype for swiftmailer874fb95
[MonologBundle] Refactored the configuration of processors Discussion ---------- Monolog This refactors the way processors and email prototype are configured in MonologBundle for consistency with the other bundles. The hack using ``@id`` to use a service in the semantic configuration is not used anywhere else in Symfony2. This removes the ability to use a static callback as processor (or a PHP function) but adds the support of adding a processor only for a given logging channel (for processors attached to the logger) which was not possible previously. --------------------------------------------------------------------------- by stof at 2011/07/06 07:33:52 -0700 the PR for the doc and the standard edition are coming.
This commit is contained in:
commit
498f72ce9c
25
UPDATE.md
25
UPDATE.md
@ -12,6 +12,31 @@ RC4 to RC5
|
|||||||
* Removed the guesser for the Choice constraint as the constraint only knows
|
* Removed the guesser for the Choice constraint as the constraint only knows
|
||||||
about the valid keys, and not their values.
|
about the valid keys, and not their values.
|
||||||
|
|
||||||
|
* The configuration of MonologBundle has been refactored.
|
||||||
|
|
||||||
|
* Only services are supported for the processors. They are now registered
|
||||||
|
using the `monolog.processor` tag which accept three optionnal attributes:
|
||||||
|
|
||||||
|
* `handler`: the name of an handler to register it only for a specific handler
|
||||||
|
* `channel`: to register it only for one logging channel (exclusive with `handler`)
|
||||||
|
* `method`: The method used to process the record (`__invoke` is used if not set)
|
||||||
|
|
||||||
|
* The email_prototype for the `SwiftMailerHandler` only accept a service id now.
|
||||||
|
|
||||||
|
* Before:
|
||||||
|
|
||||||
|
email_prototype: @acme_demo.monolog.email_prototype
|
||||||
|
|
||||||
|
* After:
|
||||||
|
|
||||||
|
email_prototype: acme_demo.monolog.email_prototype
|
||||||
|
|
||||||
|
or if you want to use a factory for the prototype:
|
||||||
|
|
||||||
|
email_prototype:
|
||||||
|
id: acme_demo.monolog.email_prototype
|
||||||
|
method: getPrototype
|
||||||
|
|
||||||
* To avoid security issues, HTTP headers coming from proxies are not trusted
|
* To avoid security issues, HTTP headers coming from proxies are not trusted
|
||||||
anymore by default (like `HTTP_X_FORWARDED_FOR`, `X_FORWARDED_PROTO`, and
|
anymore by default (like `HTTP_X_FORWARDED_FOR`, `X_FORWARDED_PROTO`, and
|
||||||
`X_FORWARDED_HOST`). If your application is behind a reverse proxy, add the
|
`X_FORWARDED_HOST`). If your application is behind a reverse proxy, add the
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Bundle\MonologBundle\DependencyInjection\Compiler;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers processors in Monolg loggers or handlers.
|
||||||
|
*
|
||||||
|
* @author Christophe Coevoet <stof@notk.org>
|
||||||
|
*/
|
||||||
|
class AddProcessorsPass implements CompilerPassInterface
|
||||||
|
{
|
||||||
|
public function process(ContainerBuilder $container)
|
||||||
|
{
|
||||||
|
if (!$container->hasDefinition('monolog.logger')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($container->findTaggedServiceIds('monolog.processor') as $id => $tags) {
|
||||||
|
foreach ($tags as $tag) {
|
||||||
|
if (!empty($tag['channel']) && !empty($tag['handler'])) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('you cannot specify both the "handler" and "channel" attributes for the "monolog.processor" tag on service "%s"', $id));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($tag['handler'])) {
|
||||||
|
$definition = $container->getDefinition(sprintf('monolog.handler.%s', $tag['handler']));
|
||||||
|
} elseif (!empty($tag['channel'])) {
|
||||||
|
if ('app' === $tag['channel']) {
|
||||||
|
$definition = $container->getDefinition('monolog.logger');
|
||||||
|
} else {
|
||||||
|
$definition = $container->getDefinition(sprintf('monolog.logger.%s', $tag['channel']));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$definition = $container->getDefinition('monolog.logger_prototype');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($tag['method'])) {
|
||||||
|
$processor = array(new Reference($id), $tag['method']);
|
||||||
|
} else {
|
||||||
|
// If no method is defined, fallback to use __invoke
|
||||||
|
$processor = new Reference($id);
|
||||||
|
}
|
||||||
|
$definition->addMethodCall('pushProcessor', array($processor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,6 @@ class Configuration implements ConfigurationInterface
|
|||||||
|
|
||||||
$rootNode
|
$rootNode
|
||||||
->fixXmlConfig('handler')
|
->fixXmlConfig('handler')
|
||||||
->fixXmlConfig('processor')
|
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('handlers')
|
->arrayNode('handlers')
|
||||||
->canBeUnset()
|
->canBeUnset()
|
||||||
@ -74,10 +73,19 @@ class Configuration implements ConfigurationInterface
|
|||||||
->scalarNode('from_email')->end() // swift_mailer and native_mailer
|
->scalarNode('from_email')->end() // swift_mailer and native_mailer
|
||||||
->scalarNode('to_email')->end() // swift_mailer and native_mailer
|
->scalarNode('to_email')->end() // swift_mailer and native_mailer
|
||||||
->scalarNode('subject')->end() // swift_mailer and native_mailer
|
->scalarNode('subject')->end() // swift_mailer and native_mailer
|
||||||
->scalarNode('email_prototype')->end() // swift_mailer
|
->arrayNode('email_prototype') // swift_mailer
|
||||||
|
->canBeUnset()
|
||||||
|
->beforeNormalization()
|
||||||
|
->ifString()
|
||||||
|
->then(function($v) { return array('id' => $v); })
|
||||||
|
->end()
|
||||||
|
->children()
|
||||||
|
->scalarNode('id')->isRequired()->end()
|
||||||
|
->scalarNode('factory-method')->defaultNull()->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
->scalarNode('formatter')->end()
|
->scalarNode('formatter')->end()
|
||||||
->end()
|
->end()
|
||||||
->append($this->getProcessorsNode())
|
|
||||||
->validate()
|
->validate()
|
||||||
->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type']) && 1 !== count($v['handler']); })
|
->ifTrue(function($v) { return ('fingers_crossed' === $v['type'] || 'buffer' === $v['type']) && 1 !== count($v['handler']); })
|
||||||
->thenInvalid('The handler has to be specified to use a FingersCrossedHandler or BufferHandler')
|
->thenInvalid('The handler has to be specified to use a FingersCrossedHandler or BufferHandler')
|
||||||
@ -101,23 +109,8 @@ class Configuration implements ConfigurationInterface
|
|||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->append($this->getProcessorsNode())
|
|
||||||
;
|
;
|
||||||
|
|
||||||
return $treeBuilder;
|
return $treeBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getProcessorsNode()
|
|
||||||
{
|
|
||||||
$treeBuilder = new TreeBuilder();
|
|
||||||
$node = $treeBuilder->root('processors');
|
|
||||||
|
|
||||||
$node
|
|
||||||
->canBeUnset()
|
|
||||||
->performNoDeepMerging()
|
|
||||||
->prototype('scalar')->end()
|
|
||||||
;
|
|
||||||
|
|
||||||
return $node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -49,10 +49,6 @@ class MonologExtension extends Extension
|
|||||||
|
|
||||||
$logger = $container->getDefinition('monolog.logger_prototype');
|
$logger = $container->getDefinition('monolog.logger_prototype');
|
||||||
|
|
||||||
if (!empty($config['processors'])) {
|
|
||||||
$this->addProcessors($container, $logger, $config['processors']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$handlers = array();
|
$handlers = array();
|
||||||
foreach ($config['handlers'] as $name => $handler) {
|
foreach ($config['handlers'] as $name => $handler) {
|
||||||
$handlers[] = array('id' => $this->buildHandler($container, $name, $handler), 'priority' => $handler['priority'] );
|
$handlers[] = array('id' => $this->buildHandler($container, $name, $handler), 'priority' => $handler['priority'] );
|
||||||
@ -190,7 +186,11 @@ class MonologExtension extends Extension
|
|||||||
|
|
||||||
case 'swift_mailer':
|
case 'swift_mailer':
|
||||||
if (isset($handler['email_prototype'])) {
|
if (isset($handler['email_prototype'])) {
|
||||||
$prototype = $this->parseDefinition($handler['email_prototype']);
|
if (!empty($handler['email_prototype']['method'])) {
|
||||||
|
$prototype = array(new Reference($handler['email_prototype']['id']), $handler['email_prototype']['method']);
|
||||||
|
} else {
|
||||||
|
$prototype = new Reference($handler['email_prototype']['id']);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$message = new Definition('Swift_Message');
|
$message = new Definition('Swift_Message');
|
||||||
$message->setFactoryService('mailer');
|
$message->setFactoryService('mailer');
|
||||||
@ -238,9 +238,6 @@ class MonologExtension extends Extension
|
|||||||
if (!empty($handler['formatter'])) {
|
if (!empty($handler['formatter'])) {
|
||||||
$definition->addMethodCall('setFormatter', array(new Reference($handler['formatter'])));
|
$definition->addMethodCall('setFormatter', array(new Reference($handler['formatter'])));
|
||||||
}
|
}
|
||||||
if (!empty($handler['processors'])) {
|
|
||||||
$this->addProcessors($container, $definition, $handler['processors']);
|
|
||||||
}
|
|
||||||
$container->setDefinition($handlerId, $definition);
|
$container->setDefinition($handlerId, $definition);
|
||||||
|
|
||||||
return $handlerId;
|
return $handlerId;
|
||||||
@ -250,25 +247,4 @@ class MonologExtension extends Extension
|
|||||||
{
|
{
|
||||||
return sprintf('monolog.handler.%s', $name);
|
return sprintf('monolog.handler.%s', $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function addProcessors(ContainerBuilder $container, Definition $definition, array $processors)
|
|
||||||
{
|
|
||||||
foreach (array_reverse($processors) as $processor) {
|
|
||||||
$definition->addMethodCall('pushProcessor', array($this->parseDefinition($processor, $container)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function parseDefinition($definition, ContainerBuilder $container = null)
|
|
||||||
{
|
|
||||||
if (0 === strpos($definition, '@')) {
|
|
||||||
$definition = substr($definition, 1);
|
|
||||||
if ($container && $container->hasDefinition($definition)) {
|
|
||||||
$container->getDefinition($definition)->setPublic(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Reference($definition);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $definition;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
|
|||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
|
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
|
||||||
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass;
|
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass;
|
||||||
|
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\AddProcessorsPass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bundle.
|
* Bundle.
|
||||||
@ -29,5 +30,6 @@ class MonologBundle extends Bundle
|
|||||||
|
|
||||||
$container->addCompilerPass(new LoggerChannelPass());
|
$container->addCompilerPass(new LoggerChannelPass());
|
||||||
$container->addCompilerPass(new DebugHandlerPass());
|
$container->addCompilerPass(new DebugHandlerPass());
|
||||||
|
$container->addCompilerPass(new AddProcessorsPass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
<parameter key="monolog.handler.debug.class">Symfony\Bridge\Monolog\Handler\DebugHandler</parameter>
|
<parameter key="monolog.handler.debug.class">Symfony\Bridge\Monolog\Handler\DebugHandler</parameter>
|
||||||
<parameter key="monolog.handler.swift_mailer.class">Monolog\Handler\SwiftMailerHandler</parameter>
|
<parameter key="monolog.handler.swift_mailer.class">Monolog\Handler\SwiftMailerHandler</parameter>
|
||||||
<parameter key="monolog.handler.native_mailer.class">Monolog\Handler\NativeMailerHandler</parameter>
|
<parameter key="monolog.handler.native_mailer.class">Monolog\Handler\NativeMailerHandler</parameter>
|
||||||
<parameter key="monolog.processor.web.class">Symfony\Bridge\Monolog\Processor\WebProcessor</parameter>
|
|
||||||
<parameter key="monolog.processor.introspection.class">Monolog\Processor\IntrospectionProcessor</parameter>
|
|
||||||
</parameters>
|
</parameters>
|
||||||
|
|
||||||
<services>
|
<services>
|
||||||
@ -32,11 +30,5 @@
|
|||||||
<service id="monolog.logger_prototype" class="%monolog.logger.class%" abstract="true">
|
<service id="monolog.logger_prototype" class="%monolog.logger.class%" abstract="true">
|
||||||
<argument /><!-- Channel -->
|
<argument /><!-- Channel -->
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="monolog.processor.web" class="%monolog.processor.web.class%" scope="request" public="false">
|
|
||||||
<argument type="service" id="request" />
|
|
||||||
</service>
|
|
||||||
|
|
||||||
<service id="monolog.processor.introspection" class="%monolog.processor.introspection.class%" public="false" />
|
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -10,16 +10,15 @@
|
|||||||
<xsd:complexType name="config">
|
<xsd:complexType name="config">
|
||||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
<xsd:element name="handler" type="handler" />
|
<xsd:element name="handler" type="handler" />
|
||||||
<xsd:element name="processor" type="xsd:string" />
|
|
||||||
</xsd:choice>
|
</xsd:choice>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:complexType name="handler">
|
<xsd:complexType name="handler">
|
||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
<xsd:element name="processor" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
<xsd:element name="email-prototype" type="email-prototype" minOccurs="0" maxOccurs="1" />
|
||||||
<xsd:element name="member" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
<xsd:element name="member" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
|
||||||
</xsd:sequence>
|
</xsd:sequence>
|
||||||
<xsd:attribute name="type" type="xsd:string" use="required" />
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
<xsd:attribute name="priority" type="xsd:integer" />
|
<xsd:attribute name="priority" type="xsd:integer" />
|
||||||
<xsd:attribute name="level" type="level" />
|
<xsd:attribute name="level" type="level" />
|
||||||
<xsd:attribute name="bubble" type="xsd:boolean" />
|
<xsd:attribute name="bubble" type="xsd:boolean" />
|
||||||
@ -35,7 +34,6 @@
|
|||||||
<xsd:attribute name="from-email" type="xsd:string" />
|
<xsd:attribute name="from-email" type="xsd:string" />
|
||||||
<xsd:attribute name="to-email" type="xsd:string" />
|
<xsd:attribute name="to-email" type="xsd:string" />
|
||||||
<xsd:attribute name="subject" type="xsd:string" />
|
<xsd:attribute name="subject" type="xsd:string" />
|
||||||
<xsd:attribute name="email-prototype" type="xsd:string" />
|
|
||||||
<xsd:attribute name="formatter" type="xsd:string" />
|
<xsd:attribute name="formatter" type="xsd:string" />
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
@ -56,4 +54,9 @@
|
|||||||
<xsd:enumeration value="550" />
|
<xsd:enumeration value="550" />
|
||||||
</xsd:restriction>
|
</xsd:restriction>
|
||||||
</xsd:simpleType>
|
</xsd:simpleType>
|
||||||
|
|
||||||
|
<xsd:complexType name="email-prototype">
|
||||||
|
<xsd:attribute name="id" type="xsd:string" />
|
||||||
|
<xsd:attribute name="method" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
|
@ -35,21 +35,6 @@ class MonologExtensionTest extends TestCase
|
|||||||
$this->assertDICConstructorArguments($handler, array('%kernel.logs_dir%/%kernel.environment%.log', \Monolog\Logger::DEBUG, true));
|
$this->assertDICConstructorArguments($handler, array('%kernel.logs_dir%/%kernel.environment%.log', \Monolog\Logger::DEBUG, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLoadWithProcessor()
|
|
||||||
{
|
|
||||||
$container = new ContainerBuilder();
|
|
||||||
$loader = new MonologExtension();
|
|
||||||
|
|
||||||
$loader->load(array(array('handlers' => array('main' => array('type' => 'stream', 'processors' => array('@monolog.processor.web'))))), $container);
|
|
||||||
$this->assertTrue($container->hasDefinition('monolog.handler.main'));
|
|
||||||
|
|
||||||
$handler = $container->getDefinition('monolog.handler.main');
|
|
||||||
$this->assertDICDefinitionMethodCallAt(0, $handler, 'pushProcessor', array(new Reference('monolog.processor.web')));
|
|
||||||
|
|
||||||
$this->assertTrue($container->getDefinition('monolog.processor.web')->isPublic());
|
|
||||||
$this->assertFalse($container->getDefinition('monolog.processor.introspection')->isPublic());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testLoadWithCustomValues()
|
public function testLoadWithCustomValues()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
Reference in New Issue
Block a user