Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding filename and line number to Monolog output

Tags:

php

monolog

Couldn't find a way to add a the file name and the line number from which the log function was called. I'm using a simple StreamHandler:

$this->log = new Logger('APP');
$this->log->pushHandler(new StreamHandler('/logs/app.log', Logger::DEBUG));

and I would like an output of something like that:

[2017-12-27 12:38:58 filename.php:1234] APP.DEBUG: test 

or any other format which includes the file name and line number.

Thanks and best regards

like image 735
asmadeus Avatar asked Dec 27 '17 12:12

asmadeus


1 Answers

It's late, but I figured out how to do it and I'm gonna post to someone else.

First, you need to create your own Processor with a new record key to be parsed (I named it as file_info):

class MyProcessor
{
    /**
     * @param  array $record
     * @return array
     */
    public function __invoke(array $record)
    {
      $info = $this->findFile();
      $record['file_info'] = $info['file'] . ':' . $info['line'];
      return $record;
    }

    public function findFile() {
      $debug = debug_backtrace();
      return [
        'file' => $debug[3] ? basename($debug[3]['file']) : '',
        'line' => $debug[3] ? $debug[3]['line'] : ''
      ];
    }
}

I used debug_backtrace to get the third element basename file and line, I'm not sure if it will work every time though.

Then, create your Logger with a custom LineFormatter (I got this part from here):

use Monolog\Logger;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\StreamHandler;

// the default date format is "Y-m-d\TH:i:sP"
$dateFormat = "Y n j, g:i a";
// the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
$output = "[%datetime% %file_info%] %channel%.%level_name%: %message% %context% %extra%\n";
// finally, create a formatter
$formatter = new LineFormatter($output, $dateFormat);
// Create a handler
$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
$stream->setFormatter($formatter);
// bind it to a logger object
$myLogger = new Logger('mylogger');
$myLogger->pushHandler($stream);

Now, you can use $myLogger->error('Foo'); and the result will be:

[2021 2 24, 6:19 pm ProductController.php:50] mylogger.ERROR: Foo [] []
like image 189
Lucius Avatar answered Oct 19 '22 10:10

Lucius