adrian7's avatar

Configure monolog handler for lumen

I am trying to configure monolog to use a custom stream handler via $app->configureMonologUsing but calling the function leads to an error

Fatal error: Call to undefined method Laravel\Lumen\Application::configureMonologUsing() .

Did anyone tried to do this, or has a possible resolution?

Thanks.

0 likes
12 replies
wheeler's avatar

I came across this trying to integrate the New Relic handler in Lumen.

Haven't got there yet, but I can tell you that your problem is exactly as stated, there is no method configureMonologUsing() in Laravel\Lumen\Application.

There is a protected method getMonologHandler().

From SO, the most promising solution is:

You'll need to extend \Laravel\Lumen\Application and override the registerLogBindings() and/or getMonologHandler() method to set up your own logging config.

1 like
wheeler's avatar

You'll need to extend \Laravel\Lumen\Application and override the registerLogBindings() and/or getMonologHandler() method to set up your own logging config.

@adrian7 i've created a gist which shows how I got it working.

https://gist.github.com/stevethomas/ec497a3d2936754ab799

For brevity:

<?php namespace Foo;

use Monolog\Logger;
use Laravel\Lumen\Application;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\NewRelicHandler;
class Hodor extends Application
{
    /**
     * Register container bindings for the application.
     *
     * @return void
     */
    protected function registerLogBindings()
    {
        $this->singleton('Psr\Log\LoggerInterface', function () {
            return new Logger('lumen', $this->getMonologHandler());
        });
    }
    /**
     * Extends the default logging implementation with additional handlers if configured in .env
     *
     * @return array of type \Monolog\Handler\AbstractHandler
     */
    protected function getMonologHandler()
    {
        $handlers = [];
        $handlers[] = (new StreamHandler(storage_path('logs/lumen.log'), Logger::DEBUG))->setFormatter(new LineFormatter(null, null, true, true));
        if (extension_loaded('newrelic')) {
            // configure New Relic monolog Handler
            newrelic_set_appname(env('APP_NAME', 'Hodor v2'));
            $handlers[] = new NewRelicHandler(Logger::ERROR, true);
        }
        return $handlers;
    }
}
3 likes
Aris's avatar

thanks @wheeler this worked for me too. Just don't forget to remove the array from the binding:

Incorrect:

return new Logger('lumen', [ $this->getMonologHandler() ]);

Correct:

return new Logger('lumen', $this->getMonologHandler());
codersrini's avatar

@wheeler Thanks for this.

I just tried to extend to create daily log files based on the log level.

 protected function getMonologHandler()
    {
        $d  =   date('Y-m-d');
        $handlers       = [];
        $handlers[]     =   (new StreamHandler(storage_path("logs/ln_info_{$d}.log"), Logger::INFO))->setFormatter(new LineFormatter(null, null, true, true));
        $handlers[]     =   (new StreamHandler(storage_path("logs/ln_warning_{$d}.log"), Logger::WARNING))->setFormatter(new LineFormatter(null, null, true, true));
        $handlers[]     =   (new StreamHandler(storage_path("logs/ln_error_{$d}.log"), Logger::ERROR))->setFormatter(new LineFormatter(null, null, true, true));
        $handlers[]     =   (new StreamHandler(storage_path("logs/ln_critical_{$d}.log"), Logger::CRITICAL))->setFormatter(new LineFormatter(null, null, true, true));
        
        return $handlers;           
    }

Log::info('Sent data'); When I try to log the data, multiple log files are created, with the same log data instead of in just one file.

The similar code has worked for me in Laravel but creates multiple files in Lumen. Any clue what I'm missing?

Serra's avatar

@codersrini You should try with RotatingFileHandler.

$handlers[] = (new RotatingFileHandler(storage_path("logs/media_info.log"), 0, Logger::INFO, false))->setFormatter(new LineFormatter(null, null, true, true));
1 like
Serra's avatar

It is possible to set monolog handlers without extending the Lumen application.

$handlers = [];

$handlers[] = (new RotatingFileHandler(storage_path("logs/media_critical.log"), 0, Logger::CRITICAL, false))->setFormatter(new LineFormatter(null, null, true, true));

$handlers[] = (new RotatingFileHandler(storage_path("logs/media_error.log"), 0, Logger::ERROR, false))->setFormatter(new LineFormatter(null, null, true, true));

$handlers[] = (new RotatingFileHandler(storage_path("logs/media_warning.log"), 0, Logger::WARNING, false))->setFormatter(new LineFormatter(null, null, true, true));

$handlers[] = (new RotatingFileHandler(storage_path("logs/media_info.log"), 0, Logger::INFO, false))->setFormatter(new LineFormatter(null, null, true, true));

app('Psr\Log\LoggerInterface')->setHandlers($handlers);
2 likes
codersrini's avatar

Im new to Laravel, Lumen & Monolog. Thanks for the info on RotatingFileHandler and option to set handlers without extending the Lumen application. Both worked. But, still when I log data using,

Log::info($log_msg); 

$log_msg is written into all the log level files (media_critical-2016-01-09.log, media_error-2016-01-09.log, media_info-2016-01-09.log, media_warning-2016-01-09.log)

Serra's avatar

@codersrini When bubble parameter is set to false in Rotating File Handler and the handlers are listed in a decreasing priority order, it should work.

teachme's avatar

Another way without extending Lumen application:

$app->configureMonologUsing(function ($logger) {
    $handlers = [
        // List your handlers here
    ];

    $logger->setHandlers($handlers);
});
2 likes

Please or to participate in this conversation.