5
votes

During the execution of Symfony Commands, I want to log messages to a different file. I have read the Symfony and Monolog documentation, and it should work like I describe here. (Note that I know messages from the 'doctrine', 'event', ... channels will still be logged by the main handler, but that doesn't matter for me)

In my config.yml, I have this:

monolog:
    channels: [commandline]
    handlers:
        main:
            type:  stream
            path:  "%kernel.logs_dir%/%kernel.environment%.main.log"
            level: debug
            channels: [!commandline]
        commandline:
            type:  stream
            path:  "%kernel.logs_dir%/%kernel.environment%.commandline.log"
            level: debug
            channels: commandline
        stdout:
            type:  stream
            path:  "php://stdout"
            level: debug
            channels: commandline
        mail:
            type:         stream
            action_level: alert
            handler:      buffered_mail
        buffered_mail:
            type:    buffer
            handler: swift
        swift:
            type:       swift_mailer
            from_email: [email protected]
            to_email:   [email protected]
            subject:    "Something went wrong"
            level:      alert

I'm expecting to have 2 log-files: dev.main.log and dev.commandline.log. But I'm still having a third log-file: dev.log that logs all messages. I don't seem to find where that loghandler is defined and how I can prevent it from logging things...

If anyone could point me in the right direction, that would be nice!

btw, i'm using:

  • symfony 2.3
  • monolog-bundle 2.4

EDIT

There is no monolog section in the config_dev.yml

2
add the monolog section of your config_dev.yml to the question please.Nicolai Fröhlich
I can confirm that I have monolog both in dev and prod config files but dev DOES NOT record entries if I don't explicitly call app_dev.php. So, it's some minconfiguration that you have encountered...Jovan Perovic
@nifr You suggestion is very valid indeed. @Stivni The only think that differs in you configuration from mine is that I use fingers_crossed strategy in main loggerJovan Perovic
I think he might have removed the overwriting main handler from his config_dev but didnt clear his (opcode-)cache or something like that. In symfony standard this default handler producing logs/<env>.log is configured in config.yml / config_dev.yml and nowhere else. The only other reason could be a missing path somewhere in the other handlers as %kernel.logs_dir%/%kernel.environment%.log is the defaultValue of path.Nicolai Fröhlich
@nifr These are the kind of suggestions I expected in the first place. Maybe you should include them in you answer, I will revoke my downvote then. But: I cleared my cache and noticed no change. Your suggestion about the defaultValue of path seems more like what I experience. I'm going to investigate it further. If I find the solution, I'll let you know.Stivni

2 Answers

5
votes

REMOVE monolog.handlers.mainfrom config_dev.yml.

It usally contains path: "%kernel.logs_dir%/%kernel.environment%.log"

config _dev.yml (default)

monolog:
    handlers:
        main:   # <- remove this handler
            type:   stream
            path:   "%kernel.logs_dir%/%kernel.environment%.log" #<- logs/dev.log
            level:  debug

Remove the main handler from this config file.

2
votes

If anyone comes across this and is still interested in why this happens, the debug handler is injected in the \Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\DebugHandlerPass::process() method...

class DebugHandlerPass implements CompilerPassInterface
{
    // ...

    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition('profiler')) {
            return;
        }

        if (!$container->getParameter('kernel.debug')) {
            return;
        }

        $debugHandler = new Definition('%monolog.handler.debug.class%', array(Logger::DEBUG, true));
        $container->setDefinition('monolog.handler.debug', $debugHandler);

        foreach ($this->channelPass->getChannels() as $channel) {
            $container
                ->getDefinition($channel === 'app' ? 'monolog.logger' : 'monolog.logger.'.$channel)
                ->addMethodCall('pushHandler', array(new Reference('monolog.handler.debug')));
        }
    }
}

As you can see, this pushes a new handler on to every registered channel, thus overriding any other handlers that might already have been added.