0

I have a Laravel project. I would like to pass an optional custom parameter (domain ID) when creating log entries. I am logging to a MySQL database via a custom Monolog event handler, based on this tutorial:.

I have searched but cannot find any solutions for what appears to be a relatively simple problem, there's a number of posts discussing things like adding user ID but none consider a simple optional parameter. Any help would be much appreciated!

Laravel: 8.27 PHP: 8.0.2

As per the tutorial, I have configured a custom handler and I can see how to use session variables or similar for customer

As per the tutorial, I have this custom handler:

namespace App\Logging;
use DB;
use Illuminate\Support\Facades\Auth;
use Monolog\Logger;
use Monolog\Handler\AbstractProcessingHandler;
class MySQLLoggingHandler extends AbstractProcessingHandler{

    public function __construct($level = Logger::DEBUG, $bubble = true) {
        parent::__construct($level, $bubble);
    }
    protected function write(array $record):void
    {
        $remote_addr = '127.0.0.1';
        if (isset( $_SERVER['REMOTE_ADDR'])) {$remote_addr = $_SERVER['REMOTE_ADDR'];}
        $user_agent = 'Unknown';
        if (isset( $_SERVER['HTTP_USER_AGENT'])) {$user_agent = $_SERVER['HTTP_USER_AGENT'];}
        $data = array(
            'message'       => $record['message'],
            'context'       => json_encode($record['context']),
            'level'         => $record['level'],
            'level_name'    => $record['level_name'],
            'channel'       => $record['channel'],
            'record_datetime' => $record['datetime']->format('Y-m-d H:i:s'),
            'extra'         => json_encode($record['extra']),
            'formatted'     => $record['formatted'],
            'remote_addr'   => $remote_addr,
            'user_agent'    => $user_agent,
            'created_at'    => date("Y-m-d H:i:s"),
        );
        DB::connection()->table('log_entries')->insert($data);
    }
}

And the custom logger class that uses it:

namespace App\Logging;
use Monolog\Logger;
class MySQLCustomLogger{
    /**
     * Custom Monolog instance.
     */
    public function __invoke(array $config){
        $logger = new Logger("MySQLLoggingHandler");
        return $logger->pushHandler(new MySQLLoggingHandler());
    }
}

The above works great for pushing logs to the database like this:

Log::info("New record created for domain id".$domain_id);

Unfortunately this makes searching the database painful when looking for enties for a specific ID, I was hoping to be able to add an option parameter like this:

Log::info("New record created for domain", $domain_id);

Mr Fett
  • 7,979
  • 5
  • 20
  • 21
  • Sorry, typo in "customer" should be custom but I cannot edit at the moment ("An error occurred submitting the edit.") – Mr Fett May 30 '23 at 09:35

1 Answers1

0

If you log the following way

Log::info('New record created for domain id', ['domain_id' => $domain_id]);

This should be accessible on the extra parameter on the array.

protected function write(array $record):void
{
    ...

    $data = [
        ...
        'domain_id' => $record['context']['domain_id'],
    ];

For a better understanding, the $record is actually a type of Log Record, which will help understanding what capabilities the $record property has.

mrhn
  • 17,961
  • 4
  • 27
  • 46
  • Thansk @mrhn, I tried the above and I get the following error:Undefined array key "domain_id". It works fine if I just push a number directly in to the domain_id field w – Mr Fett May 30 '23 at 14:42
  • dd($record['extra']); in the handler returns an empty array [ ] – Mr Fett May 30 '23 at 14:44
  • What if you change the typehint from array to LogRecord and dd($record->extra); – mrhn May 30 '23 at 15:36
  • So it turns out I had to do $record['context']['domain_id'] to retrieve the value - thanks for the hint! – Mr Fett Jun 01 '23 at 21:11
  • great it helped i updated the answer to help others in the future – mrhn Jun 02 '23 at 06:55