feature #24425 [Console][HttpKernel] Handle new SHELL_VERBOSITY env var, also configures the default logger (nicolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[Console][HttpKernel] Handle new SHELL_VERBOSITY env var, also configures the default logger

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

On the CLI, the behavior of the new default logger is not nice: it's verbosity is controlled by `kernel.debug`, where I would expect to be able to control it by mean of verbosity.
To achieve this, I propose to handle a new `SHELL_VERBOSITY` env var, and use it to control both commands' verbosity, and the logger's log level.

Commits
-------

87bd741f2d [Console][HttpKernel] Handle new SHELL_VERBOSITY, also configures the default logger
This commit is contained in:
Fabien Potencier 2017-10-10 10:53:03 -07:00
commit 6231acc8e8
7 changed files with 53 additions and 23 deletions

View File

@ -895,18 +895,37 @@ class Application
}
}
switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {
case -1: $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); break;
case 1: $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); break;
case 2: $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); break;
case 3: $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); break;
default: $shellVerbosity = 0; break;
}
if (true === $input->hasParameterOption(array('--quiet', '-q'), true)) {
$output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
$input->setInteractive(false);
$shellVerbosity = -1;
} else {
if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || 3 === $input->getParameterOption('--verbose', false, true)) {
$output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
$shellVerbosity = 3;
} elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || 2 === $input->getParameterOption('--verbose', false, true)) {
$output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
$shellVerbosity = 2;
} elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) {
$output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
$shellVerbosity = 1;
}
}
if (-1 === $shellVerbosity) {
$input->setInteractive(false);
}
putenv('SHELL_VERBOSITY='.$shellVerbosity);
$_ENV['SHELL_VERBOSITY'] = $shellVerbosity;
$_SERVER['SHELL_VERBOSITY'] = $shellVerbosity;
}
/**

View File

@ -4,6 +4,7 @@ CHANGELOG
3.4.0
-----
* added `SHELL_VERBOSITY` env var to control verbosity
* added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11
`ContainerCommandLoader` for commands lazy-loading
* added a case-insensitive command name matching fallback

View File

@ -1580,6 +1580,13 @@ class ApplicationTest extends TestCase
$this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found');
}
}
protected function tearDown()
{
putenv('SHELL_VERBOSITY');
unset($_ENV['SHELL_VERBOSITY']);
unset($_SERVER['SHELL_VERBOSITY']);
}
}
class CustomApplication extends Application

View File

@ -12,7 +12,6 @@
namespace Symfony\Component\HttpKernel\DependencyInjection;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Symfony\Component\HttpKernel\Log\Logger;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -29,17 +28,14 @@ class LoggerPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
$alias = $container->setAlias(LoggerInterface::class, 'logger');
$alias->setPublic(false);
$container->setAlias(LoggerInterface::class, 'logger')
->setPublic(false);
if ($container->has('logger')) {
return;
}
$loggerDefinition = $container->register('logger', Logger::class);
$loggerDefinition->setPublic(false);
if ($container->getParameter('kernel.debug')) {
$loggerDefinition->addArgument(LogLevel::DEBUG);
}
$container->register('logger', Logger::class)
->setPublic(false);
}
}

View File

@ -177,6 +177,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
if (false === $this->booted) {
if ($this->debug && !isset($_SERVER['SHELL_VERBOSITY'])) {
putenv('SHELL_VERBOSITY=3');
$_ENV['SHELL_VERBOSITY'] = 3;
$_SERVER['SHELL_VERBOSITY'] = 3;
}
$this->boot();
}

View File

@ -37,15 +37,28 @@ class Logger extends AbstractLogger
private $formatter;
private $handle;
public function __construct($minLevel = LogLevel::WARNING, $output = 'php://stderr', callable $formatter = null)
public function __construct($minLevel = null, $output = 'php://stderr', callable $formatter = null)
{
if (!$minLevel) {
$minLevel = LogLevel::WARNING;
if (isset($_SERVER['SHELL_VERBOSITY'])) {
switch ((int) $_SERVER['SHELL_VERBOSITY']) {
case -1: $minLevel = LogLevel::ERROR; break;
case 1: $minLevel = LogLevel::NOTICE; break;
case 2: $minLevel = LogLevel::INFO; break;
case 3: $minLevel = LogLevel::DEBUG; break;
}
}
}
if (!isset(self::$levels[$minLevel])) {
throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $minLevel));
}
$this->minLevelIndex = self::$levels[$minLevel];
$this->formatter = $formatter ?: array($this, 'format');
if (false === $this->handle = @fopen($output, 'a')) {
if (false === $this->handle = is_resource($output) ? $output : @fopen($output, 'a')) {
throw new InvalidArgumentException(sprintf('Unable to open "%s".', $output));
}
}

View File

@ -13,7 +13,6 @@ namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Symfony\Component\HttpKernel\DependencyInjection\LoggerPass;
use Symfony\Component\HttpKernel\Log\Logger;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@ -54,15 +53,4 @@ class LoggerPassTest extends TestCase
$this->assertSame(Logger::class, $definition->getClass());
$this->assertFalse($definition->isPublic());
}
public function testSetMinLevelWhenDebugging()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.debug', true);
(new LoggerPass())->process($container);
$definition = $container->getDefinition('logger');
$this->assertSame(LogLevel::DEBUG, $definition->getArgument(0));
}
}