monolog-bundle icon indicating copy to clipboard operation
monolog-bundle copied to clipboard

Channels are ignored for nested handlers

Open ostrolucky opened this issue 4 years ago • 8 comments

I am trying to come up with sane default way to configure monolog in our applications and came up with these conditions:

  1. Application MUST always log application specific >= INFO messages
  2. Application MUST log non-application specific messages in case of error ONLY
  3. Application MUST log application specific DEBUG messages in case of error ONLY
  4. 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 and main_grouped handlers as a gateway for error condition mentioned in points 2. and 3.
  • we have non_app handler for getting all messages except app, 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.

ostrolucky avatar Nov 19 '20 16:11 ostrolucky

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.

Pictor13 avatar Nov 24 '20 20:11 Pictor13

Changing bubble doesn't seem to have an effect :/

ostrolucky avatar Nov 24 '20 22:11 ostrolucky

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"

ostrolucky avatar Nov 24 '20 23:11 ostrolucky

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.

syntaxseed avatar Nov 18 '21 14:11 syntaxseed

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.

stof avatar Nov 18 '21 14:11 stof

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.

Hmm... I don't actually want a fingers_crossed handler for app. Just a normal one.

syntaxseed avatar Nov 18 '21 14:11 syntaxseed

then, put !app as channel on your main handler rather than on its nested main_handler handler.

stof avatar Nov 18 '21 14:11 stof

then, put !app as channel on your main handler rather than on its nested main_handler handler.

That worked. Thank you!

syntaxseed avatar Nov 22 '21 15:11 syntaxseed