5

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: some@email.com
            to_email:   some@email.com
            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

Stivni
  • 437
  • 1
  • 6
  • 15
  • add the `monolog` section of your `config_dev.yml` to the question please. – Nicolai Fröhlich Dec 05 '13 at 11:35
  • 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 Dec 05 '13 at 11:36
  • @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` logger – Jovan Perovic Dec 05 '13 at 11:43
  • 1
    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/.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](https://github.com/symfony/MonologBundle/blob/master/DependencyInjection/Configuration.php#L215)**. – Nicolai Fröhlich Dec 05 '13 at 11:53
  • @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 Dec 05 '13 at 12:47

2 Answers2

5

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.

Nicolai Fröhlich
  • 51,330
  • 11
  • 126
  • 130
  • This is just hiding the problem: Symfony, Monolog or something else is using a loghandler and a logfile, I didn't define. I want to find out where and why. – Stivni Dec 05 '13 at 11:04
  • 1
    Thanks for the **downvote** on a legitimate answer that would help other users in 99% of the cases ?! ... because `config_dev.yml` overwrites the `main` handler from `config.yml` and introduces the logfile `dev.log` in dev-environment. Good luck solving this ... i honestly hope nobody else will answer. Did you try removing the `main` handler with the path to that logfile from `config_dev.yml` ? What is **hiding** the problem here ... explain ! – Nicolai Fröhlich Dec 05 '13 at 11:26
  • 2
    My question was: "Why does Symfony still log to a dev.log file, even when I didn't define it in a loghandler?" - I think you answer doesn't address the question. Instead of explaining why this could happen, you just assume there are other handlers defined. Well: there are no additional handlers in the `config_dev.yml` file. You're suggestion is also ignoring the fact that I maybe **want** to suffix my log files. I think the downvote is as legitimate as you think your answer is... – Stivni Dec 05 '13 at 12:38
  • @Stivni i just read his answer 4 years later and it solved a problem for me – Edward Jun 23 '17 at 16:34
  • 1
    @Edward 4years later ... how cool is that? Glad I could help - made my day, thanks for leaving the comment :) – Nicolai Fröhlich Jun 24 '17 at 14:39
2

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.

TobyG
  • 1,692
  • 3
  • 21
  • 36