Skip to content

Commit

Permalink
[MonologBridge] added integration with the console component
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobion authored and fabpot committed Jun 4, 2013
1 parent e160ddb commit c0b5996
Show file tree
Hide file tree
Showing 5 changed files with 414 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/Symfony/Bridge/Monolog/CHANGELOG.md
@@ -1,6 +1,12 @@
CHANGELOG
=========

2.4.0
-----

* added ConsoleHandler and ConsoleFormatter which can be used to show log messages
in the console output depending on the verbosity settings

2.1.0
-----

Expand Down
47 changes: 47 additions & 0 deletions src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php
@@ -0,0 +1,47 @@
<?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\Bridge\Monolog\Formatter;

use Monolog\Formatter\LineFormatter;
use Monolog\Logger;

/**
* Formats incoming records for console output by coloring them depending on log level.
*
* @author Tobias Schultze <http://tobion.de>
*/
class ConsoleFormatter extends LineFormatter
{
const SIMPLE_FORMAT = "%start_tag%[%datetime%] %channel%.%level_name%:%end_tag% %message% %context% %extra%\n";

/**
* {@inheritdoc}
*/
public function format(array $record)
{
if ($record['level'] >= Logger::ERROR) {
$record['start_tag'] = '<error>';
$record['end_tag'] = '</error>';
} elseif ($record['level'] >= Logger::NOTICE) {
$record['start_tag'] = '<comment>';
$record['end_tag'] = '</comment>';
} elseif ($record['level'] >= Logger::INFO) {
$record['start_tag'] = '<info>';
$record['end_tag'] = '</info>';
} else {
$record['start_tag'] = '';
$record['end_tag'] = '';
}

return parent::format($record);
}
}
186 changes: 186 additions & 0 deletions src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php
@@ -0,0 +1,186 @@
<?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\Bridge\Monolog\Handler;

use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
use Symfony\Bridge\Monolog\Formatter\ConsoleFormatter;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Writes logs to the console output depending on its verbosity setting.
*
* It is disabled by default and gets activated as soon as a command is executed.
* Instead of listening to the console events, the output can also be set manually.
*
* The minimum logging level at which this handler will be triggered depends on the
* verbosity setting of the console output. The default mapping is:
* - OutputInterface::VERBOSITY_NORMAL will show all WARNING and higher logs
* - OutputInterface::VERBOSITY_VERBOSE (-v) will show all NOTICE and higher logs
* - OutputInterface::VERBOSITY_VERY_VERBOSE (-vv) will show all INFO and higher logs
* - OutputInterface::VERBOSITY_DEBUG (-vvv) will show all DEBUG and higher logs, i.e. all logs
*
* This mapping can be customized with the $verbosityLevelMap constructor parameter.
*
* @author Tobias Schultze <http://tobion.de>
*/
class ConsoleHandler extends AbstractProcessingHandler implements EventSubscriberInterface
{
/**
* @var OutputInterface|null
*/
private $output;

/**
* @var array
*/
private $verbosityLevelMap = array(
OutputInterface::VERBOSITY_NORMAL => Logger::WARNING,
OutputInterface::VERBOSITY_VERBOSE => Logger::NOTICE,
OutputInterface::VERBOSITY_VERY_VERBOSE => Logger::INFO,
OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG
);

/**
* Constructor.
*
* @param OutputInterface|null $output The console output to use (the handler remains disabled when passing null
* until the output is set, e.g. by using console events)
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack
* @param array $verbosityLevelMap Array that maps the OutputInterface verbosity to a minimum logging
* level (leave empty to use the default mapping)
*/
public function __construct(OutputInterface $output = null, $bubble = true, array $verbosityLevelMap = array())
{
parent::__construct(Logger::DEBUG, $bubble);
$this->output = $output;

if ($verbosityLevelMap) {
$this->verbosityLevelMap = $verbosityLevelMap;
}
}

/**
* {@inheritdoc}
*/
public function isHandling(array $record)
{
return $this->updateLevel() && parent::isHandling($record);
}

/**
* {@inheritdoc}
*/
public function handle(array $record)
{
// we have to update the logging level each time because the verbosity of the
// console output might have changed in the meantime (it is not immutable)
return $this->updateLevel() && parent::handle($record);
}

/**
* Sets the console output to use for printing logs.
*
* @param OutputInterface $output The console output to use
*/
public function setOutput(OutputInterface $output)
{
$this->output = $output;
}

/**
* Disables the output.
*/
public function close()
{
$this->output = null;

parent::close();
}

/**
* Before a command is executed, the handler gets activated and the console output
* is set in order to know where to write the logs.
*
* @param ConsoleCommandEvent $event
*/
public function onCommand(ConsoleCommandEvent $event)
{
$this->setOutput($event->getOutput());
}

/**
* After a command has been executed, it disables the output.
*
* @param ConsoleTerminateEvent $event
*/
public function onTerminate(ConsoleTerminateEvent $event)
{
$this->close();
}

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
ConsoleEvents::COMMAND => 'onCommand',
ConsoleEvents::TERMINATE => 'onTerminate'
);
}

/**
* {@inheritdoc}
*/
protected function write(array $record)
{
if ($record['level'] >= Logger::ERROR && $this->output instanceof ConsoleOutputInterface) {
$this->output->getErrorOutput()->write((string) $record['formatted']);
} else {
$this->output->write((string) $record['formatted']);
}
}

/**
* {@inheritdoc}
*/
protected function getDefaultFormatter()
{
return new ConsoleFormatter();
}

/**
* Updates the logging level based on the verbosity setting of the console output.
*
* @return Boolean Whether the handler is enabled and verbosity is not set to quiet.
*/
private function updateLevel()
{
if (null === $this->output || OutputInterface::VERBOSITY_QUIET === $verbosity = $this->output->getVerbosity()) {
return false;
}

if (isset($this->verbosityLevelMap[$verbosity])) {
$this->setLevel($this->verbosityLevelMap[$verbosity]);
} else {
$this->setLevel(Logger::DEBUG);
}

return true;
}
}

0 comments on commit c0b5996

Please sign in to comment.