Skip to content

Commit aea0145

Browse files
committed
Merge branch 'feat-handler-channels' (PR #3)
2 parents 289442e + ec44bd3 commit aea0145

30 files changed

+755
-55
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
vendor
2+
composer.phar
3+
composer.lock
4+
phpunit.xml

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: php
2+
3+
php:
4+
- 5.3
5+
- 5.4
6+
7+
before_script:
8+
- curl -s http://getcomposer.org/installer | php
9+
- php composer.phar install --dev

DependencyInjection/Compiler/LoggerChannelPass.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,28 @@ public function process(ContainerBuilder $container)
4545
}
4646
}
4747
}
48+
49+
$handlersToChannels = $container->getParameter('monolog.handlers_to_channels');
50+
51+
foreach ($handlersToChannels as $handler => $channels) {
52+
foreach ($this->processChannels($channels) as $channel) {
53+
$logger = $container->getDefinition('monolog.logger.'.$channel);
54+
$logger->addMethodCall('pushHandler', array(new Reference($handler)));
55+
}
56+
}
57+
}
58+
59+
protected function processChannels($configuration)
60+
{
61+
if (null === $configuration) {
62+
return $this->channels;
63+
}
64+
65+
if ('inclusive' === $configuration['type']) {
66+
return $configuration['elements'];
67+
}
68+
69+
return array_diff($this->channels, $configuration['elements']);
4870
}
4971

5072
protected function createLogger($channel, $loggerId, ContainerBuilder $container)

DependencyInjection/Configuration.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
1515
use Symfony\Component\Config\Definition\ConfigurationInterface;
16+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1617

1718
/**
1819
* This class contains the configuration information for the bundle
@@ -84,6 +85,60 @@ public function getConfigTreeBuilder()
8485
->scalarNode('factory-method')->defaultNull()->end()
8586
->end()
8687
->end()
88+
->arrayNode('channels')
89+
->fixXmlConfig('channel', 'elements')
90+
->canBeUnset()
91+
->beforeNormalization()
92+
->ifString()
93+
->then(function($v) { return array('elements' => array($v)); })
94+
->end()
95+
->beforeNormalization()
96+
->ifTrue(function($v) { return is_array($v) && is_numeric(key($v)); })
97+
->then(function($v) { return array('elements' => $v); })
98+
->end()
99+
->validate()
100+
->ifTrue(function($v) { return empty($v); })
101+
->thenUnset()
102+
->end()
103+
->validate()
104+
->always(function ($v) {
105+
$isExclusive = null;
106+
if (isset($v['type'])) {
107+
$isExclusive = 'exclusive' === $v['type'];
108+
}
109+
110+
$elements = array();
111+
foreach ($v['elements'] as $element) {
112+
if (0 === strpos($element, '!')) {
113+
if (false === $isExclusive) {
114+
throw new InvalidConfigurationException('Cannot combine exclusive/inclusive definitions in channels list.');
115+
}
116+
$elements[] = substr($element, 1);
117+
$isExclusive = true;
118+
} else {
119+
if (true === $isExclusive) {
120+
throw new InvalidConfigurationException('Cannot combine exclusive/inclusive definitions in channels list');
121+
}
122+
$elements[] = $element;
123+
$isExclusive = false;
124+
}
125+
}
126+
127+
return array('type' => $isExclusive ? 'exclusive' : 'inclusive', 'elements' => $elements);
128+
})
129+
->end()
130+
->children()
131+
->scalarNode('type')
132+
->validate()
133+
->ifNotInArray(array('inclusive', 'exclusive'))
134+
->thenInvalid('The type of channels has to be inclusive or exclusive')
135+
->end()
136+
->end()
137+
->arrayNode('elements')
138+
->prototype('scalar')->end()
139+
->end()
140+
->end()
141+
->end()
87142
->scalarNode('formatter')->end()
88143
->end()
89144
->validate()

DependencyInjection/MonologExtension.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,14 @@ public function load(array $configs, ContainerBuilder $container)
4444
$loader->load('monolog.xml');
4545
$container->setAlias('logger', 'monolog.logger');
4646

47-
$logger = $container->getDefinition('monolog.logger_prototype');
48-
4947
$handlers = array();
48+
5049
foreach ($config['handlers'] as $name => $handler) {
51-
$handlers[] = array('id' => $this->buildHandler($container, $name, $handler), 'priority' => $handler['priority'] );
50+
$handlers[] = array(
51+
'id' => $this->buildHandler($container, $name, $handler),
52+
'priority' => $handler['priority'],
53+
'channels' => isset($handler['channels']) ? $handler['channels'] : null
54+
);
5255
}
5356

5457
$handlers = array_reverse($handlers);
@@ -59,11 +62,13 @@ public function load(array $configs, ContainerBuilder $container)
5962

6063
return $a['priority'] < $b['priority'] ? -1 : 1;
6164
});
65+
$handlersToChannels = array();
6266
foreach ($handlers as $handler) {
6367
if (!in_array($handler['id'], $this->nestedHandlers)) {
64-
$logger->addMethodCall('pushHandler', array(new Reference($handler['id'])));
68+
$handlersToChannels[$handler['id']] = $handler['channels'];
6569
}
6670
}
71+
$container->setParameter('monolog.handlers_to_channels', $handlersToChannels);
6772

6873
$this->addClassesToCompile(array(
6974
'Monolog\\Formatter\\FormatterInterface',

Resources/config/schema/monolog-1.0.xsd

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
<xsd:sequence>
1818
<xsd:element name="email-prototype" type="email-prototype" minOccurs="0" maxOccurs="1" />
1919
<xsd:element name="member" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
20+
<xsd:element name="channels" type="channels" minOccurs="0" maxOccurs="1" />
2021
</xsd:sequence>
2122
<xsd:attribute name="type" type="xsd:string" />
2223
<xsd:attribute name="priority" type="xsd:integer" />
@@ -46,6 +47,13 @@
4647
<xsd:enumeration value="critical" />
4748
<xsd:enumeration value="alert" />
4849

50+
<xsd:enumeration value="DEBUG" />
51+
<xsd:enumeration value="INFO" />
52+
<xsd:enumeration value="WARNING" />
53+
<xsd:enumeration value="ERROR" />
54+
<xsd:enumeration value="CRITICAL" />
55+
<xsd:enumeration value="ALERT" />
56+
4957
<xsd:enumeration value="100" />
5058
<xsd:enumeration value="200" />
5159
<xsd:enumeration value="300" />
@@ -59,4 +67,18 @@
5967
<xsd:attribute name="id" type="xsd:string" />
6068
<xsd:attribute name="method" type="xsd:string" />
6169
</xsd:complexType>
70+
71+
<xsd:complexType name="channels">
72+
<xsd:sequence>
73+
<xsd:element name="channel" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
74+
</xsd:sequence>
75+
<xsd:attribute name="type" type="xsd:string" />
76+
</xsd:complexType>
77+
78+
<xsd:simpleType name="channel_type">
79+
<xsd:restriction base="xsd:string">
80+
<xsd:enumeration value="inclusive" />
81+
<xsd:enumeration value="exclusive" />
82+
</xsd:restriction>
83+
</xsd:simpleType>
6284
</xsd:schema>

Tests/DependencyInjection/Compiler/LoggerChannelPassTest.php

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,28 @@ public function testProcess()
2828

2929
$service = $container->getDefinition('test');
3030
$this->assertEquals('monolog.logger.test', (string) $service->getArgument(1), '->process replaces the logger by the new one');
31+
32+
33+
// pushHandlers for service "test"
34+
$expected = array(
35+
'test' => array('monolog.handler.a', 'monolog.handler.b', 'monolog.handler.c'),
36+
'foo' => array('monolog.handler.b'),
37+
'bar' => array('monolog.handler.b', 'monolog.handler.c'),
38+
);
39+
40+
foreach ($expected as $serviceName => $handlers) {
41+
$service = $container->getDefinition($serviceName);
42+
$channel = $container->getDefinition((string) $service->getArgument(1));
43+
44+
$calls = $channel->getMethodCalls();
45+
$this->assertCount(count($handlers), $calls);
46+
foreach ($handlers as $i => $handler) {
47+
list($methodName, $arguments) = $calls[$i];
48+
$this->assertEquals('pushHandler', $methodName);
49+
$this->assertCount(1, $arguments);
50+
$this->assertEquals($handler, (string) $arguments[0]);
51+
}
52+
}
3153
}
3254

3355
protected function getContainer()
@@ -39,9 +61,29 @@ protected function getContainer()
3961
$container->set('monolog.handler.test', new Definition('%monolog.handler.null.class%', array (100, false)));
4062
$definition->addMethodCall('pushHandler', array(new Reference('monolog.handler.test')));
4163

42-
$service = new Definition('TestClass', array('false', new Reference('logger')));
43-
$service->addTag('monolog.logger', array ('channel' => 'test'));
44-
$container->setDefinition('test', $service);
64+
// Handlers
65+
$container->set('monolog.handler.a', new Definition('%monolog.handler.null.class%', array (100, false)));
66+
$container->set('monolog.handler.b', new Definition('%monolog.handler.null.class%', array (100, false)));
67+
$container->set('monolog.handler.c', new Definition('%monolog.handler.null.class%', array (100, false)));
68+
69+
// Channels
70+
foreach (array('test', 'foo', 'bar') as $name) {
71+
$service = new Definition('TestClass', array('false', new Reference('logger')));
72+
$service->addTag('monolog.logger', array ('channel' => $name));
73+
$container->setDefinition($name, $service);
74+
}
75+
76+
$container->setParameter('monolog.handlers_to_channels', array(
77+
'monolog.handler.a' => array(
78+
'type' => 'inclusive',
79+
'elements' => array('test')
80+
),
81+
'monolog.handler.b' => null,
82+
'monolog.handler.c' => array(
83+
'type' => 'exclusive',
84+
'elements' => array('foo')
85+
)
86+
));
4587

4688
$container->getCompilerPassConfig()->setOptimizationPasses(array());
4789
$container->getCompilerPassConfig()->setRemovingPasses(array());

0 commit comments

Comments
 (0)