Saving command logger output to log file and console - php

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"]

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

Symfony messenger is printing massive output through stderr

I have a worker that needs to retry consuming some messages until an external service is available to store them, which is only available on work hours, but the events can be generated at any time.
Everything is working as expected, and I'm logging both stderr and stout for traceability purposes. This is a business decision and there's now way around it, so no .log files. But symfony messenger seems to be outputting massive amounts of data, mostly related to redelivery and delay stamps, and my logs are getting out of hand.
These outputs have no valuable information and seem to be serialized stamps. And there's thousands of them every hour:
:67:\\\"\\0Symfony\\\\Component\\\\Messenger\\\\Stamp\\\\RedeliveryStamp\\0...
:51:\\\"\\0Symfony\\\\Component\\\\Messenger\\\\Stamp\\\\DelayStamp\\0delay...
I have no custom middlewares and nothing is printed in my own code.
I tried configuring monolog to ignore messenger and doctrine related entries with no luck:
channels: ["!event", "!doctrine", "!messenger", "!security"]
This is what my messenger.yaml looks like:
framework:
messenger:
failure_transport: failed
transports:
failed: 'doctrine://default?queue_name=failed'
async:
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
retry_strategy:
max_retries: 14400
delay: 300000
multiplier: 1
max_delay: 300000
options:
queue_name: redacted_queue_name
routing:
'App\Domain\UserCreatedEvent [async]
Am I missing some obvious way to disable this output?
Edit: this is what my monolog.yaml looks like:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: nested
excluded_http_codes: [404, 405]
path: "php://stdout"
channels: ["!event", "!doctrine", "!messenger", "!security"]
nested:
type: stream
path: "php://stdout"
channels: ["!event", "!doctrine", "!messenger", "!security"]
console:
level: warning
type: console
process_psr_3_messages: false
channels: ["!event", "!doctrine", "!messenger", "!security"]
deprecation:
type: stream
path: "php://stdout"
deprecation_filter:
type: filter
handler: deprecation
max_level: info
channels: ["php"]

monolog configuration in symfony and customization

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');

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.

Symfony do not log deprecations

i want the log to behave like the regular php-log in production.
There is a logrotate in place and the server-logs are analyzed with other tools.
So i set up my config_prod.yml like that:
monolog:
use_microseconds: false
handlers:
main:
type: error_log
level: WARNING
deduplicated:
type: deduplication
time: 60
handler: main
Somehow the deprecations (via #trigger_error) appear in my log, too.
Can i disable the logging of the deprecations somehow?
I don't need them in prod but only in dev.
Kind regards.
Patrick
You can try to exclude a channel php from your handler
use_microseconds: false
handlers:
main:
type: error_log
level: WARNING
deduplicated:
type: deduplication
time: 60
handler: main
channels: ['!php']

Categories