Search code examples
symfonyredissymfony4monolog

Symfony 4 enable logging with Monolog's Redis handler


I have a working ELK stack connected to Redis.

I also have a working stateless Symfony 4 application and I want to send all the production logs to my Redis.

I know Monolog has a Redis handler, but I don't know how I'm supposed to tweak the config/prod/monolog.yaml file to accomplish this of if there’s another approach.

This is how it looks right now:

monolog:
handlers:
    main:
        type: fingers_crossed
        action_level: error
        handler: nested
        excluded_http_codes: [404]
    nested:
        type: stream
        path: "php://stderr"
        level: debug
    console:
        type: console
        process_psr_3_messages: false
        channels: ["!event", "!doctrine"]
    deprecation:
        type: stream
        path: "php://stderr"
    deprecation_filter:
        type: filter
        handler: deprecation
        max_level: info
        channels: ["php"]

Solution

  • The approach I took was, first installing the predis client:

    composer require predis/predis
    

    Then create a custom service class that extends the RedisHandler class that comes with the Monolog package:

    namespace App\Service\Monolog\Handler;
    
    use Monolog\Handler\RedisHandler;
    use Monolog\Logger;
    use Predis\Client as PredisClient;
    
    class Redis extends RedisHandler
    {
        public function __construct( $host, $port = 6379, $level = Logger::DEBUG, $bubble = true, $capSize = false)
        {
            $predis = new PredisClient( "tcp://$host:$port" );
            $key = 'logstash';
    
            parent::__construct($predis, $key, $level, $bubble, $capSize);
        }
    }
    

    Next, activate the service we just created on the services.yml config file:

    services:    
      monolog.handler.redis:
        class: App\Service\Monolog\Handler\Redis
        arguments: [ '%redis.host%' ]
    

    Be sure the parameter redis.host is set and points to your Redis server. In my case, my parameter value is the IP of my Redis server.

    I added other parameters to the class like port and log level. You can set it at the moment of instantiating your service like with the host parameter.

    Finally, configure your custom log handler service in your monolog.yaml config file. In my case, I need it only the production logs with the config as follow:

    handlers:
      custom:
        type: service
        id: monolog.handler.redis
        level: debug
        channels: ['!event']