Search code examples
symfonyloggingmonolog

Monolog handler ignoring yaml level


In Symfony 4.3 using Monolog, I have created a custom handler to push logs to AWS Firehose. Here is the constructor:

class FirehoseLogHandler extends AbstractProcessingHandler {

public function __construct(
        FirehoseClient $firehoseClient,
        FormatterInterface $formatter,
        $streamName,
        $level = Logger::INFO,
        $bubble = true
    ) {

        $this->firehoseClient = $firehoseClient;
        $this->streamName = $streamName;
        $this->formatter = $formatter;

        parent::__construct($level, $bubble);
    }

And here is my monolog.yaml config:

monolog:
  handlers:
    firehose_handler:
      type: service
      id: kinesis_stream_handler

    main:
      type: stream
      handler: firehose_handler
      level: error
      channels: ["!event"]

services:
  kinesis_stream_handler:
    class: App\Logger\Handler\FirehoseLogHandler
    arguments:
      $firehoseClient: '@aws.firehose'
      $formatter: '@App\Logger\Formatter\FirehoseLogFormatter'
      $streamName: 'firehose-stream-test'

The problem that I am having is that the $level is always set to Logger::INFO (200), or whatever is set in the constructor. It seems to be ignoring what is set in the yaml config.

What am I doing wrong here? I know I could always add $level: 400 to the service declaration but that doesn't seem to make much sense. Appreciate any help in advance.


Solution

  • Handlers defined as type: service are used strictly as-is, since they are instances you have already constructed. They are not passed any arguments from the main monolog configuration; that would only apply to services it is constructing for you. So you do need to add $level as an explicit argument to your custom handler for this reason.

    There may be some further confusion stemming from your main handler definition. While handler is a valid configuration key, it does not apply to a stream handler as it only makes sense for handlers that wrap others, such as filter. So that is simply being ignored.

    The full list of handler types and what configuration keys actually apply to each can be found in the code here.