Skip to content

How to Configure Monolog to Display Console Messages

Edit this page

It is possible to use the console to print messages for certain verbosity levels using the OutputInterface instance that is passed when a command is run.

When a lot of logging has to happen, it's cumbersome to print information depending on the verbosity settings (-v, -vv, -vvv) because the calls need to be wrapped in conditions. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
use Symfony\Component\Console\Output\OutputInterface;

public function __invoke(OutputInterface $output): int
{
    if ($output->isDebug()) {
        $output->writeln('Some info');
    }

    if ($output->isVerbose()) {
        $output->writeln('Some more info');
    }

    // ...
}

Instead of using these semantic methods to test for each of the verbosity levels, the MonologBridge provides a ConsoleHandler that listens to console events and writes log messages to the console output depending on the current log level and the console verbosity.

The example above could then be rewritten as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Command/MyCommand.php
namespace App\Command;

use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;

#[AsCommand(name: 'app:my-command')]
class MyCommand
{
    public function __construct(
        private LoggerInterface $logger,
    ) {
    }

    public function __invoke(): int
    {
        $this->logger->debug('Some info');
        $this->logger->notice('Some more info');

        return Command::SUCCESS;
    }
}

Depending on the verbosity level that the command is run in and the user's configuration (see below), these messages may or may not be displayed to the console. If they are displayed, they are time-stamped and colored appropriately. Additionally, error logs are written to the error output (php://stderr). There is no need to conditionally handle the verbosity settings anymore.

LoggerInterface Verbosity Command line
->error() OutputInterface::VERBOSITY_QUIET stderr
->warning() OutputInterface::VERBOSITY_NORMAL stdout
->notice() OutputInterface::VERBOSITY_VERBOSE -v
->info() OutputInterface::VERBOSITY_VERY_VERBOSE -vv
->debug() OutputInterface::VERBOSITY_DEBUG -vvv

The Monolog console handler is enabled by default:

1
2
3
4
5
6
7
8
9
10
11
12
13
# config/packages/monolog.yaml
when@dev:
    monolog:
        handlers:
            # ...
            console:
                type:   console
                process_psr_3_messages: false
                channels: ['!event', '!doctrine', '!console']

                # optionally configure the mapping between verbosity levels and log levels
                # verbosity_levels:
                #     VERBOSITY_NORMAL: NOTICE

Note

In this configuration, console is an arbitrary handler name and can be any string. The type: console option selects the ConsoleHandler, which writes log messages to the command output.

The channels option uses the ! prefix to exclude specific channels. The console channel is excluded to reduce noise. This is the channel where Symfony logs command lifecycle events (e.g. Command "{command}" exited with code "{code}"). Excluding this channel does not affect any log messages you write yourself inside your commands, which use different channels and will still appear normally.

Now, log messages will be shown on the console based on the log levels and verbosity. By default (normal verbosity level), warnings and higher will be shown. But in full verbosity mode, all messages will be shown.

Filtering Logs by Channel

In high verbosity modes, the logs of all channels can make the output hard to read. For example, when a command fails while calling an external API, you may only want to see the logs of the http_client channel. Instead of changing the channels option of the handler and clearing the cache, define the SYMFONY_CONSOLE_LOG_CHANNELS environment variable when running the command:

1
2
3
4
5
6
7
8
9
# display only the logs of the "http_client" channel
$ SYMFONY_CONSOLE_LOG_CHANNELS=http_client php bin/console app:import -vvv

# display the logs of several channels (use a comma-separated list)
$ SYMFONY_CONSOLE_LOG_CHANNELS=app,http_client php bin/console app:import -vvv

# display the logs of all channels except some (prefix them with "!")
# (you can't mix included and excluded channels in the same list)
$ SYMFONY_CONSOLE_LOG_CHANNELS='!php,!cache' php bin/console app:import -vvv

The logs hidden from the console are still sent to the other handlers (e.g. the one that writes to var/log/dev.log). This variable only filters the channels allowed by the channels option of the handler. For example, with the configuration shown above, SYMFONY_CONSOLE_LOG_CHANNELS=doctrine displays nothing because that option excludes the doctrine channel.

8.2

The SYMFONY_CONSOLE_LOG_CHANNELS environment variable was introduced in Symfony 8.2.

Limiting Output to Interactive Mode

In automated environments like CI/CD pipelines or cron jobs, console log output may interfere with command output or create unnecessary clutter. You can configure the console handler to only output logs when the console is interactive:

1
2
3
4
5
6
7
8
# config/packages/dev/monolog.yaml
monolog:
    handlers:
        console:
            type: console
            process_psr_3_messages: false
            channels: ['!event', '!doctrine', '!console']
            interactive_only: true

When interactive_only is set to true, the console handler will only output logs and prevent propagation to other handlers when the command is running in an interactive terminal. In non-interactive mode (e.g., when using the --no-interaction option or in automated scripts), logs will be propagated to other handlers instead.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version