Skip to content

Commit

Permalink
[MonologBundle] Added the MonologBundle
Browse files Browse the repository at this point in the history
  • Loading branch information
Seldaek authored and stof committed Mar 18, 2011
1 parent 341a296 commit 6114ccc
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MonologBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\NodeBuilder;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;

/**
* This class contains the configuration information for the bundle
*
* This information is solely responsible for how the different configuration
* sections are normalized, and merged.
*
* @author Jordi Boggiano <[email protected]>
*/
class Configuration
{
/**
* Generates the configuration tree.
*
* @return \Symfony\Component\Config\Definition\NodeInterface
*/
public function getConfigTree()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('monolog', 'array');

// TODO update XSD to match this
$rootNode
->arrayNode('handlers')
->fixXmlConfig('handler')
->canBeUnset()
->performNoDeepMerging()
->prototype('array')
->performNoDeepMerging()
// TODO lowercase the type always
->scalarNode('type')->isRequired()->end()
->scalarNode('action_level')->end()
->scalarNode('level')->defaultValue('INFO')->end()
->scalarNode('path')->end()
->scalarNode('bubble')->end()
->scalarNode('buffer_size')->end()
->arrayNode('handler')
->performNoDeepMerging()
->scalarNode('type')->isRequired()->end()
->scalarNode('level')->defaultValue('DEBUG')->end()
->scalarNode('path')->end()
->end()
->end()
->end()
;

return $treeBuilder->buildTree();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MonologBundle\DependencyInjection;

use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Parameter;

/**
* MonologExtension is an extension for the Monolog library.
*
* @author Jordi Boggiano <[email protected]>
*/
class MonologExtension extends Extension
{
/**
* Loads the Monolog configuration.
*
* Usage example:
*
* monolog:
* handlers:
* myhandler:
* level: info
* path: path/to/some.log
*
* @param array $config An array of configuration settings
* @param ContainerBuilder $container A ContainerBuilder instance
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$processor = new Processor();
$config = $processor->process($configuration->getConfigTree(), $configs);

if (isset($config['handlers'])) {
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('monolog.xml');
$container->setAlias('logger', 'monolog.logger');

$logger = $container->getDefinition('monolog.logger');

$handlers = array();
foreach ($config['handlers'] as $handler) {
$handlers[] = $this->buildHandler($container, $handler);
}

// TODO somehow the DebugLogger should be pushed on the stack as well, or that concept needs to be changed
// didn't have to investigate yet what it is exactly
$handlers = array_reverse($handlers);
foreach ($handlers as $handler) {
$logger->addMethodCall('pushHandler', array($handler));
}
}
}

public function buildHandler(ContainerBuilder $container, array $handler)
{
$definition = new Definition(new Parameter('monolog.handler.'.$handler['type'].'.class'));
$handler['level'] = is_int($handler['level']) ? $handler['level'] : constant('Monolog\Logger::'.strtoupper($handler['level']));

switch ($handler['type']) {
case 'stream':
if (!isset($handler['path'])) {
$handler['path'] = '%kernel.logs_dir%/%kernel.environment%.log';
}

$definition->setArguments(array(
$handler['path'],
$handler['level'],
isset($handler['bubble']) ? $handler['bubble'] : false,
));
break;

case 'fingerscrossed':
if (!isset($handler['handler'])) {
// TODO validate that in Config class?
throw new \InvalidArgumentException('Handler sub-node is missing.');
}
if (!isset($handler['action_level'])) {
$handler['action_level'] = 'WARNING';
}
$handler['action_level'] = is_int($handler['action_level']) ? $handler['action_level'] : constant('Monolog\Logger::'.strtoupper($handler['action_level']));

$definition->setArguments(array(
$this->buildHandler($container, $handler['handler']),
$handler['action_level'],
isset($handler['buffer_size']) ? $handler['buffer_size'] : 0,
isset($handler['bubble']) ? $handler['bubble'] : false,
));
break;
}

return $definition;
}

/**
* Returns the base path for the XSD files.
*
* @return string The XSD base path
*/
public function getXsdValidationBasePath()
{
return __DIR__.'/../Resources/config/schema';
}

public function getNamespace()
{
return 'http://www.symfony-project.org/schema/dic/monolog';
}
}
40 changes: 40 additions & 0 deletions src/Symfony/Bundle/MonologBundle/Logger/DebugLogger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MonologBundle\Logger;

use Monolog\Handler\TestHandler;
use Monolog\Logger;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;

/**
* DebugLogger.
*
* @author Jordi Boggiano <[email protected]>
*/
class DebugLogger extends TestHandler implements DebugLoggerInterface
{
/**
* {@inheritdoc}
*/
public function getLogs()
{
return $this->messages;
}

/**
* {@inheritdoc}
*/
public function countErrors()
{
return count($this->messagesByLevel[Logger::ERROR]);
}
}
47 changes: 47 additions & 0 deletions src/Symfony/Bundle/MonologBundle/Logger/Logger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MonologBundle\Logger;

use Monolog\Logger as BaseLogger;
use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;

/**
* Logger.
*
* @author Fabien Potencier <[email protected]>
*/
class Logger extends BaseLogger implements LoggerInterface
{
/**
* Returns a DebugLoggerInterface instance if one is registered with this logger.
*
* @return DebugLoggerInterface A DebugLoggerInterface instance or null if none is registered
*/
public function getDebugLogger()
{
$handler = $this->handler;
while ($handler) {
if ($handler instanceof DebugLoggerInterface) {
return $handler;
}
$handler = $handler->getParent();
}

return null;
}

public function log($message, $level)
{
return $this->addMessage($level, $message);
}
}
23 changes: 23 additions & 0 deletions src/Symfony/Bundle/MonologBundle/MonologBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MonologBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

/**
* Bundle.
*
* @author Jordi Boggiano <[email protected]>
*/
class MonologBundle extends Bundle
{
}
18 changes: 18 additions & 0 deletions src/Symfony/Bundle/MonologBundle/Resources/config/monolog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" ?>

<container xmlns="http://www.symfony-project.org/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd">

<parameters>
<parameter key="monolog.logger.class">Symfony\Bundle\MonologBundle\Logger\Logger</parameter>
<parameter key="monolog.handler.stream.class">Monolog\Handler\StreamHandler</parameter>
<parameter key="monolog.handler.fingerscrossed.class">Monolog\Handler\FingersCrossedHandler</parameter>
</parameters>

<services>
<service id="monolog.logger" class="%monolog.logger.class%" public="false">
<argument>framework</argument>
</service>
</services>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns="http://www.symfony-project.org/schema/dic/monolog"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.symfony-project.org/schema/dic/monolog"
elementFormDefault="qualified">

<xsd:element name="config" type="config" />

<xsd:complexType name="config">
<xsd:all>
<xsd:element name="handler" type="handler" minOccurs="0" maxOccurs="unbounded" />
</xsd:all>
</xsd:complexType>

<xsd:complexType name="handler">
<xsd:attribute name="level" type="level" />
<xsd:attribute name="path" type="xsd:string" />
</xsd:complexType>

<xsd:simpleType name="level">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="error" />
<xsd:enumeration value="warning" />
<xsd:enumeration value="info" />
<xsd:enumeration value="debug" />

<xsd:enumeration value="100" />
<xsd:enumeration value="200" />
<xsd:enumeration value="300" />
<xsd:enumeration value="400" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
22 changes: 22 additions & 0 deletions src/Symfony/Bundle/MonologBundle/Tests/TestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MonologBundle\Tests;

class TestCase extends \PHPUnit_Framework_TestCase
{
protected function setUp()
{
if (!class_exists('Monolog\Logger')) {
$this->markTestSkipped('Monolog is not available.');
}
}
}

0 comments on commit 6114ccc

Please sign in to comment.