monolog-bundle
monolog-bundle copied to clipboard
Channels are ignored for nested handlers
I am trying to come up with sane default way to configure monolog in our applications and came up with these conditions:
- Application MUST always log application specific >= INFO messages
- Application MUST log non-application specific messages in case of error ONLY
- Application MUST log application specific DEBUG messages in case of error ONLY
- Application MUST NOT log same message twice, eg. app INFO or DEBUG message
I assumed this would work:
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: main_grouped
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
include_stacktraces: true
main_grouped:
type: group
members: [ non_app, app_debug]
non_app:
type: stream
path: "%kernel.logs_dir%/non-app.log"
channels: ["!app"]
app_debug:
type: stream
path: "%kernel.logs_dir%/app_debug.log"
channels: ["app"]
level: debug
# info and higher levels messages should be always logged for app channels
app:
type: stream
path: "%kernel.logs_dir%/app.log"
level: info
channels: ["app"]
So here:
- we have
app
handler taking care of 1st condition - we have
main
andmain_grouped
handlers as a gateway for error condition mentioned in points 2. and 3. - we have
non_app
handler for getting all messages exceptapp
, conforming with point 2. - we have
app_debug
handler for getting all application debug messages, conforming with point 3.
Now, problem is that non_app
handler doesn't care that I am excluding app
channel via channels: ["!app"]
. This results in message in app
channel going through both app
and non_app
handlers in case of error happening.
Mmmh, wondering why !app
doesn't work. However did you try to play with the bubble: false
setting?
I'm not sure every handlers supports that but it might help your case; or maybe specifying some filter.
Changing bubble
doesn't seem to have an effect :/
This issue also makes it pretty much impossible to have fingers crossed handler that is not listening to request
or console
, as that's the channel which is used for logging errors. As such, something like this (which is part of bigger config and this part specifically is meant to log only messages from app channel when error happens) doesn't work, because either monolog.logger.request
or monolog.logger.console
is used for unhandled errors, but both of them have NullHandler injected only.
monolog:
handlers:
main_nonapp:
type: fingers_crossed
action_level: error
handler: app_debug
channels: ["app_debug"]
app_debug:
type: stream
path: "%kernel.logs_dir%/app_debug.log"
Can confirm this bug. I can't get the exclusion of "!app" to work in main_handler
. So app channel logs get logged in 2 places.
monolog:
handlers:
main:
type: fingers_crossed
action_level: error
handler: main_handler #nested
excluded_http_codes: [404, 405]
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
formatter: monolog.formatter.standard
main_handler:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.errors.log"
level: notice
channels: ["!event", "!app"]
formatter: monolog.formatter.standard
app:
type: stream
path: "%kernel.logs_dir%/%kernel.environment%.app.log"
level: notice
channels: ["app"]
formatter: monolog.formatter.standard
I have to either accept it as is, or not use a fingers_crossed
handler.
Well, channels are separate Monolog\Logger
instances that receives handlers. So configuring channels on nested handlers indeed will have no effect: the main
handler is injected in all channels, and it is this handler that calls your main_handler
handler.
If you want different configuration for app
, you need to create a different fingers_crossed
handler for that channel.
Well, channels are separate
Monolog\Logger
instances that receives handlers. So configuring channels on nested handlers indeed will have no effect: themain
handler is injected in all channels, and it is this handler that calls yourmain_handler
handler. If you want different configuration forapp
, you need to create a differentfingers_crossed
handler for that channel.
Hmm... I don't actually want a fingers_crossed handler for app. Just a normal one.
then, put !app
as channel on your main
handler rather than on its nested main_handler
handler.
then, put
!app
as channel on yourmain
handler rather than on its nestedmain_handler
handler.
That worked. Thank you!