Search code examples
symfonymonolog

I can't write logs to a file using a specific channel with Monolog in Symfony 3.4


I try to write logs to a specific file using a specific channel in Monolog (called encuestas_cloud) inside a Command in Symfony 3.4 but I'm not able to do it.

I've read Symfony docs and searched in the web and I think it's well configured but i get an error.

The code is:

In config_dev.yml:

monolog:

  handlers:
    main:
        type: stream
        path: '%kernel.logs_dir%/%kernel.environment%.log'
        level: debug
        channels: ['!event']

  ...
    encuestas_cloud_logger:
        #type: rotating_file
        type: stream
        path: 'D:/web/xampp/htdocs/temp/logs/encuestas_cloud.log'
        level: info
        channels: ['encuestas_cloud']   
        max_files: 10       

In services.yml

services:
  _defaults:
     autowire: true
     autoconfigure: true
     public: false

  AppBundle\Command\EncuestasCloudCommand\:
    resource: '../../src/AppBundle/Command/EncuestasCloudCommand.php'
    arguments: ['@logger']
    public: true
    tags:
        - { name: monolog.logger, channel: encuestas_cloud } 

The command:

// src/AppBundle/Command/EncuestasCloudCommand.php
namespace AppBundle\Command;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
...

class EncuestasCloudCommand extends ContainerAwareCommand

{
  private $logger;

  public function __construct(LoggerInterface $logger)
  {
    $this->logger = $logger;
    parent::__construct();
  }

 ...
 protected function execute(InputInterface $input, OutputInterface $output)
 {

    $logger = $this->logger;
    $logger->addInfo('My logger is now ready');

When I execute it I get:

In LoggerChannelPass.php line 98:

Monolog configuration error: The logging channel "encuestas_cloud" assigned to the
"encuestas_cloud_logger" handler does not exist.

In ContainerBuilder.php line 1063:

You have requested a non-existent service "monolog.logger.encuestas_cloud".

If I add channels: ['encuestas_cloud'] in config_dev.yml

monolog:
  channels: ['encuestas_cloud'] 

  handlers:
    main:
        type: stream
...

The error dissappear but the log still goes to the general log file: dev.log

Please, could somebody help me to find out what is wrong with the configuration?

Thanks a lot!!!


Solution

  • Thanks a lot evertjes for your answer, it didn't solve the problem but helped me to investigate other paths...

    The problem was that the command wasn't defined as a service in the right way, so Symfony was unable to match the channel to the service (and to the command).

    I executed :

    php bin/console debug:container
    

    and the service of the command didn't appear.

    So after investigating how to define a command as a service the configuration worked fine... uffff.

    Here I post the final code that works.

    In config_dev.yml:

    monolog:
      channels: ['encuestas_cloud']
    
      handlers:
        main:
            type: stream
            path: '%kernel.logs_dir%/%kernel.environment%.log'
            level: debug
            channels: ['!event','!encuestas_cloud']
    
      ...
        encuestas_cloud_logger:
            type: rotating_file
            path: 'D:/web/xampp/htdocs/temp/logs/encuestas_cloud.log'
            level: info
            channels: ['encuestas_cloud']   
            max_files: 10       
    

    In services.yml

    services:
      _defaults:
         autowire: true
         autoconfigure: true
         public: false
    
      console.command.encuestas_cloud_command:
        class: 'AppBundle\Command\EncuestasCloudCommand'
        arguments: ['@logger']
        public: true
        tags:
            - { name: monolog.logger, channel: encuestas_cloud }  
    

    The command:

    // src/AppBundle/Command/EncuestasCloudCommand.php
    namespace AppBundle\Command;
    use Psr\Log\LoggerInterface;
    use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
    ...
    
    class EncuestasCloudCommand extends ContainerAwareCommand
    
    {
      private $logger;
    
      public function __construct(LoggerInterface $logger)
      {
        $this->logger = $logger;
        parent::__construct();
      }
    
     ...
     protected function execute(InputInterface $input, OutputInterface $output)
     {
    
        $logger = $this->logger;
        $logger->addInfo('My logger is now ready');
    

    Now the file is created and the log appears with the configured channel.

    Thanks a lot to everybody!!!