I want to log into a different file than the usual dev.log or prod.log
I know that this can be done with different channels and I used it in several services, but I'm not very clear about switching the Monolog channel in a controller.
In a service you just define the channel via the tags
attribute in the service definition, but how can I do this in a controller or even better in a specific action?
I know that a possible solution would be this: Symfony 2 : Log into a specific file
But it seems overkill to define two new services just for logging to a custom file.
The only way to do this is to define your controller as a service and inject a custom logger with a custom channel.
Since the channels are created automatically there is currently no other way, but it's an interesting request and you're not the first, so I created an issue on MonologBundle to allow the definition of channels at the bundle configuration level. That way you could just fetch the proper logger from the controller using $this->get('monolog.logger.mychannel')
(which you can already do if the channel exists, but not if you want a custom channel for the controller that nothing else uses).
Update:
As of symfony/monolog-bundle 2.4.0 you can define additional channels as:
monolog:
channels: ["foo", "bar"]
Then you can retrieve it as $this->get('monolog.logger.mychannel')
I know that this is an older post, but I ran into a similar need using symfony/monolog-bundle 2.1.x. I couldn't seem to find exactly what I needed in other threads, so I'm documenting my solution here, which was to create a logger container that used a custom channel.
In config.yml
monolog:
handlers:
user_actions:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%-user-actions.log"
level: info
channels: [user_actions]
In my bundle's services.yml
acme.logger.user_actions:
class: Acme\MyBundle\Monolog\UserActionsLogger
arguments: ['@logger']
tags:
- { name: monolog.logger, channel: user_actions }
In src/Acme/MyBundle/Monolog/UserActionsLogger.php
<?php
namespace Acme\MyBundle\Monolog;
class UserActionsLogger
{
public $logger;
public function __construct($logger)
{
$this->logger = $logger;
}
}
Then you can either inject the logger container into another service with:
acme.user.authenticationhandler:
class: %acme.user.authenticationhandler.class%
public: false
arguments: ['@router', '@security.context', '@acme.logger.user_actions']
Or, you could selectively use the logger container as a service in any controller:
$userActionsLogger = $this->get('acme.logger.user_actions');
Then you can access the actual logger by:
$userActionsLogger->logger->info('A thing happened!')
I am currently using symfony/monolog-bundle 2.3.0 and the following code works.
Configuration in config.yml
monolog:
handlers:
main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: info
doctrine:
type: stream
path: %kernel.logs_dir%/doctrine_%kernel.environment%.log
level: debug
channels: doctrine
On Controllers
$doctrineLogger = $this->get('monolog.logger.doctrine');
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With