New in Symfony 2.4: Show logs in console

I’m happy to announce a new feature that will be available in Symfony 2.4: You can automatically show your log messages in the console output of commands.
This eases giving feedback in your console commands dramatically. Before I show you how to use this feature, let’s take a look at what problem it solves.

When you want to output text to the console you usually used the OutputInterface instance
that is passed when your command gets executed like in the following example:

But there are two problems:

  • It’s cumbersome to print information depending on the verbosity settings (-v, -vv, -vvv) because you need to wrap the calls in conditions.
  • If the service you call also wants to give feedback you would need to pass on the $output as with $myService->process($data, $output). But this is really bad
    code in terms of separation of concerns and coupling. What if this service has a dependency on another service? Working with the OutputInterface and passing around the instance is not the way to go.

To solve these things I thought it would be much easier to rely on the logger which is highly related. So I added integration between Symfonys Console Component
and Symfonys logging library Monolog in PR #8167.
It features a new handler for Monolog (ConsoleHandler) that listens to the console events
and upon activation will write log messages to the console output depending on the current log level and the console verbosity. By default this mapping between log level and verbosity is as follows:

  • 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.

Now let’s see how we can activate and configure this feature in your Symfony project. With PR #42 on the MonologBundle, I made this handler just as configurable as any other
Monolog handler. All it needs is an additional handler of type console in your config_dev.yml and config_prod.yml files.

With this in place, all messages that are logged while running a command get nicely displayed on the console. With nicely I mean that the messages
are timestamped, colored depending on the log level and error logs are even written to the error output (php://stderr).
Now you don’t need to conditionally handle the verbosity settings anymore and you can consistently use the logger instead of the OutputInterface in your commands and the services.
Your services simply use a logger as usual (injected with dependency injection) and are not coupled to the console.

In the standard edition of Symfony 2.4 this feature is now included by default with PR #557. You can even customize
the behavior as in the following example. With the verbosity_levels option you can adapt the above mentioned mapping between verbosity and log level. In the given example it will
also show notices in normal verbosity mode (instead of warnings only). Additionally, it will only use messages logged with the custom my_channel channel and it changes the
display style via a custom formatter. See also the documentation for more information.

I think this solves a common problem when working with console commands. For your information, a
different approach using AOP has been described by Matthias Noback.
Now it’s your turn to make your commands more user and developer friendly by exposing clear information on what is happening without having to resort to verbose or dirty code.

That’s a great feature, thx!

Excellent! Great idea.

Indeed it was what prevented me from doing proper logging during commands, usually reducing it to “Doing XYZ…”

Thanks :)

nice, definitely will use it since it is ingrained on sf2 already and monolog.

var i = 0;
while (1) {

Thats a really neat feature — but I guess there is no way to use it standalone with symfony/console and monolog/monolog ..

@Daniel, it is possible to use it standalone. All you need is the and then you can do something like

protected function execute(InputInterface $input, OutputInterface $output)
$this->logger = $this->getContainer()->get(‘logger’);

if ($this->logger instanceof MonologLogger) {
$this->logger->pushHandler(new SymfonyBridgeMonologHandlerConsoleHandler($output));

And you ready to use the logger which also logs to the console.

Many thanks for this, especially the answer to Daniel Leech re: using the bridge with standalone Monolog and Console. Cheers!

dantleech could you please point a repo on github where you use this standalone approach? thanks