monolog configuration in symfony and customization - php

I am working on a web app built using Symfony 2.6 and there are different configuration inside app/config folder. How do I know which one is being used.
Inside app/config I see config.yml config_dev.yml config_prod.yml and the monolog entry I see in config_dev.yml and also in monolog_prod.yml. It is as below.
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
Now I want to use monolog to input some logs in a controller and put those logs separate form other logs. How can this be done?.

You know which one is used on your environment.
If you are in dev mode you are using config_dev.yml merged with config.yml
You can check it into your virtual host if the file is on app.php you are in prod mode, if the file points to app_dev.php you are in dev mode usually
To log into other files you can create a channel like this:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
your_handler:
level: debug
type: stream
path: '%kernel.logs_dir%/custom.log'
channels: ['your_channel']
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
console:
type: console
And into your controller you can call it in this way:
$logger = $this->get('monolog.logger.your_handler');
$logger->debug('your custom message into your custom log file');

Related

How to list all build-in / pre-defined Monolog channels in Symfony?

I am new to Symfony 5.3 and Monolog. The docu explains "the Symfony Framework organizes log messages into channels. By default, there are several channels, including doctrine, event, security, request and more."
Is there any way to find out what channels exactly are configured?
I tried to run php bin/console debug:config monolog but this only shows the channels I configured (e.g. by adding channels: ['myChannelA', 'channelB'] to the monolog.yaml)
I made no changes (beside adding custom channels, see above) to the default monolog config which was created on install:
// config/packages/dev/monolog.yaml
monolog:
channels: ['myChannelA','channelB']
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
channels: ["!event"]
# uncomment to get logging in your browser
# you may have to allow bigger header sizes in your Web server configuration
#firephp:
# type: firephp
# level: info
#chromephp:
# type: chromephp
# level: info
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!console"]
// config/packages/prod/monolog.yaml
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
nested:
type: stream
path: php://stderr
level: debug
formatter: monolog.formatter.json
console:
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine"]
You can try the following command:
php bin/console debug:autowiring | grep monolog

Saving command logger output to log file and console

I wrote a very simple test command which has LoggerInterface injected in its constructor.
How am I suppose to change the monolog.yaml configuration to save this logger output to both log file and to output it to console?
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
formatter: monolog.line.formatter
handler: terminal
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
terminal:
type: stream
path: "php://stderr"
level: debug
console:
type: console
process_psr_3_messages: false
channels: [ "!event", "!doctrine" ]
The commands will always stderr by default (if you specify the -vvv option)
If you need to write the logs in a file only on error (with the stack error) you can use the finger_crossed handler :
handlers:
main:
# fingers_crossed allow to log only if action_level defined is reach
type: fingers_crossed
# minimum level to activate the handler
# available level (emergency|alert|critical|error|warning|notice|info|debug){1}
action_level: error
# wrapped handler's name
handler: nested
nested:
# stream allow to write log in file
type: stream
# path to the log file
path: "%kernel.logs_dir%/%project_name%_%kernel.environment%.log"
# available level (emergency|alert|critical|error|warning|notice|info|debug){1}
level: debug
If you want to filter a bit the logs shown in the stderr you can use the default config for the console :
console:
type: console
process_psr_3_messages: false
channels: ['!event', '!doctrine', '!console']
I'll allow you to have nicer console logs (and avoid too many "useless" logs such as event or doctrine which are very verbose)
You can use the "group" handler https://github.com/symfony/monolog-bundle/blob/master/DependencyInjection/Configuration.php#L137
Check an implementation here https://symfony.com/doc/current/logging/monolog_email.html
You can do this like your terminal handler does. copy the terminal handler and set the path to the file. Both handlers will be executed.
monolog:
handlers:
main:
...
terminal:
...
terminal_file:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%-terminal.log"
level: debug
You can also do this to log different channels to different files.
Sometimes i use this, to log doctrine debug messages to a different file, by adding the doctrine channel.
monolog:
handlers:
...
doctrine_debug:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%-doctrine.log"
level: debug
channels: ["doctrine"]

Symfony production logs

In Symfony 3 is there anyway i can write all errors to logs on production without setting the debug mode on? Errors would include http 500 errors or application errors or the php errors which are silenced due to the error flag set to false on production.
The current log config for production is
monolog:
handlers:
main:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: info
channels: [!request, !event, !translation, !kernel, !security, !php, !snc_redis]
php:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%_php.log"
level: warning
channels: [php]
You could use the default production settings (taken from the monolog-bundle recipe) for this:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_404s:
# regex: exclude all 404 errors from the logs
- ^/
nested:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.log"
level: debug
What happens with this configuration is that Monolog buffers all messages during a request, but only writes them to the log when an error appears. This way you will not "flood" your logs with noisy debug and info messages all the time. You only get full log information when there was an error during a request.

Custom monolog handler for default monolog in Symfony 2

I want to add a custom handler to a default monolog in Symfony 2.
In my config.yaml file, I have:
monolog:
handlers:
main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: debug
myHandler:
type: Acme\MyBundle\Monolog\MyCustomHandler
level: error
My class looks like below:
// Acme\MyBundle\Monolog\MyCustomHandler
use Monolog\Logger;
use Monolog\Handler\SocketHandler;
use Monolog\Formatter\LineFormatter;
class MyCustomHandler extends AbstractProcessingHandler
{
...
}
But even before I fill my class in I get an error:
invalid handler type "acme\mybundle\monolog\mycustomhandler" given for handler "myHandler"
How do I add a custom handler to the default monolog without creating a new monolog service?
Try this:
monolog:
handlers:
main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: debug
custom:
type: service
id: my_custom_handler
services:
my_custom_handler:
class: Acme\MyBundle\Monolog\MyCustomHandler
If you want to use it as default handler then you should change a bit monolog section I wrote above.
monolog:
handlers:
main:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: debug
handler: custom
custom:
type: service
id: my_custom_handler
I hope it helps you.
I just found out that Monolog ships with a set of various handlers so you might wanna use one of those instead of writing your own. I am using the LogEntriesHandler for logging to logentries.com but there are a few more as documented here: https://github.com/Seldaek/monolog#log-specific-servers-and-networked-logging
My Symfony2 config for that looks like that:
monolog:
main:
type: fingers_crossed
level: debug
handler: nested
custom:
type: service
id: monolog.handler.logentries
level: error
services:
monolog.handler.logentries:
class: Monolog\Handler\LogEntriesHandler
arguments:
token: %logentries_token%

monolog with different levels and environments

under app/config/config_dev.yml I have:
monolog:
handlers:
main:
type: stream
path: /var/log/dev.log
level: debug
and under app/config/config_prod.yml I have:
monolog:
handlers:
syslog:
type: stream
path: /var/log/prod.log
level: error
In my controller I have
$logger = $this->get('logger');
$logger->debug("foo");
I would expect to see the debug entry while in dev and only error and above entry when in prod.
But so far it's outputting everything. How can I adjust it so that different levels exists for different environments?

Categories