I want to make one Logger class which can be use in different modules in Symfony and when logging to have different channels. Here is my configurations:
service.yaml
App\Logger\MLogger:
arguments: ['#logger']
tags:
- { name: monolog.logger, channel: 'mailchimp' }
monolog.yaml - dev
monolog:
handlers:
main:
type: stream
path: "php://stderr"
level: debug
channels: ["mailchimp"]
console:
type: stream
path: "php://stderr"
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
deprecation:
type: error_log
deprecation_filter:
type: filter
handler: deprecation
max_level: info
channels: ["php"]
With this I have the custom logger and I load it with dependency injection.
Example of method inclusion:
public function send(Request $request, MLogger $logger)
The same logger class I want to use for different module and with difference channel.
How can I configure it so the Mlogger class could be used with different channels?
Related
In my Symfony app I am using monolog to log errors and I got different channels. I need to write different channels to different files. I got the following monolog config:
//app\config\config.yml
monolog:
channels: ['my_channel', 'my_channel2']
use_microseconds: false
handlers:
file:
type: stream
path: %kernel.logs_dir%/prod_info.log
level: info
channels: [!my_channel2]
file_2:
type: stream
path: %kernel.logs_dir%/mylogfile_2.log
level: info
channels: [my_channel2]
file_errors:
type: stream
path: %kernel.logs_dir%/cms_errors.log
level: error
channels: [!my_channel2]
my config.prod config
monolog:
handlers:
main:
type: fingers_crossed
action_level: debug
handler: nested
channels: [!my_channel2]
nested:
type: stream
path: "%kernel.logs_dir%/main_%kernel.environment%.log"
level: debug
channels: [!my_channel2]
console:
type: console
I can access my_channel2 in the code like this:
$logger = $this->get('monolog.logger.my_channel2');
$logger->debug('Some message here');
but still all my_channel2 messages are written to main_prod.log file instead of mylogfile_2.log. Any ideas how to fix it would be welcome. Thank you.
just needed to change action level from info to debug for the required channel
file_2:
type: stream
path: %kernel.logs_dir%/mylogfile_2.log
level: debug // <== change from info to debug here
channels: [my_channel2]
I have configured logger for different channel in different files, but it does not work for me. It's work but it writes in console not in pointed file.
And I need write log to file in channel search.
Here is my code:
#app/config/config_dev.yml
monolog:
handlers:
search:
type: stream
level: error
path: "%kernel.logs_dir%/search_log.log"
channels: [search]
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: [!event, !search]
console:
type: console
channels: [!event, !doctrine, !search]
Defined service:
#MyBundle/Resources/config/services.yml
services:
app.logger_search:
class: Symfony\Bridge\Monolog\Logger
arguments: ["#logger"]
tags:
- {name: monolog.logger, channel: search}
Now use it service, try to test it:
#MyController.php
/**
* #Route("/test")
*/
public function test()
{
$this->get("app.logger_search")->error("Test");
return $this->json("test");
}
But it writes into console insted of file.
Console I meant where I ran my server: php bin\console server:run.
Creating your own Channel. This is done either via the configuration or by tagging your service with monolog.logger and specifying which channel the service should log to (just as you have done).
Both ways are valid and in both cases you logger will be named:
monolog.logger.<you-channel-name>
So use monolog.logger.search instead of your service id app.logger_search to fix the issue.
I you don't have a strong reason to change the logger behavior, I suggest to configure additional channels without tagged services:
# app/config/config.yml
monolog:
channels: ['foo', 'bar']
With this, you can now send log messages to the foo channel by using the automatically registered logger service monolog.logger.foo.
I have read some docs here but still not clear to me how to write and use a custom Monolog handler and channel. Let me explain a bit what I want to achieve. I have a custom function and I want that log to be logged into a file called custom.log. I have enabled Doctrine logging into another file by setting this in config.yml file:
monolog:
handlers:
#Logs Doctrine to a different channel
doctrine:
level: debug
type: stream
path: "%kernel.logs_dir%/doctrine.log"
channels: [doctrine]
How do I achieve the same for a custom.log?
You can try that way,
monolog:
channels: ["testchannel"]
handlers:
test:
# log all messages (since debug is the lowest level)
level: debug
type: stream
path: "%kernel.logs_dir%/testchannel.log"
channels: ["testchannel"]
And in the controller you can get the logger and do your thing;
class DefaultController extends Controller
{
public function indexAction()
{
$logger = $this->get('monolog.logger.testchannel');
$logger->info("This one goes to test channel!!");
return $this->render('AcmeBundle:Default:index.html.twig');
}
}
Also you can check which monolog handlers and loggers are registered by running the command php app/console container:debug monolog
I'm having a hard time understanding how to configure logging in my symfony app to do what i need to. I don't understand the difference/relationship between handlers and channels. I have the following in my config.yml
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
dynamic_request:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%_dynamic.log"
level: debug
I then have this defined in my services.yml
jsonstub.dynamic.response_provider:
class: ProgrammingAreHard\JsonStub\CoreBundle\Domain\Dynamic\EventListener\DynamicResponseProvider
arguments:
- #security.context
- #logger
- %kernel.environment%
tags:
- { name: kernel.event_listener, event: security.interactive_login, method: onAuthentication }
- { name: monolog.logger, channel: dynamic_request }
The desired behavior is for only error logs to be logged to %kernel.logs_dir%/%kernel.environment%.log and then i would like to inject a logger into my DynamicResponseProvider that logs to %kernel.logs_dir%/%kernel.environment%_dynamic.log. The documentation is confusing me. It states the following:
configuration defines a stack of handlers which will be called in the order where they are defined
Does this mean that because i have the dynamic_request handler defined any debug logs will be logged here? That is not my desired behavior. What i would like is that ONLY the DynamicResponseProvider will use that handler. How can i achieve this?
You can specify a channel for a handler.
So, if you want that the 'dynamic_request' handler is used only for 'dynamic_request' logs, your config.yml must be :
dynamic_request:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%_dynamic.log"
level: debug
channels: dynamic_request
See http://symfony.com/doc/current/cookbook/logging/channels_handlers.html for more example
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
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.
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.