Laravel PHP

How to create a custom logger for Laravel

In this article, we will be looking at how to create a custom logger for Laravel. Here, we are going to create a CustomLoggerFactory and a custom Formatter to output the message.


1) Creating CustomLoggerFactory

In the app/Logger folder (create the folder if it doesn’t exist), create a new class CustomLoggerFactory.php with the following code.

namespace App\Logger;

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

/**
 * Class CustomLoggerFactory
 */
class CustomLoggerFactory
{
    /**
     * Create Monolog Logger with Custom logging format
     *
     * @param array $config
     *
     * @return Logger
     */
    public function __invoke(array $config): Logger
    {
        // Retrieve Config values
        $name = $config["name"] ?? 'my-app-name';

        // Create a log channel
        $logger = new Logger($name);

        // Create handler
        $handler = new StreamHandler('php://stdout');
        $handler->setFormatter(new JsonFormatter());

        // Create processor
        $processor = new CustomLoggerProcessor();

        // Set Logger with new Handler and Processor
        $logger->pushHandler($handler);
        $logger->pushProcessor($processor);

        return $logger;
    }
}

Here we are using the JsonFormatter, but you could create a “customFormatter” if required in another format.

We are using StreamHandler to output the log messages. This could be changed to any Log aggregator, for example, Cloud Watch, Elasticsearch etc.

2) Create a CustomLoggerProcessor

In the app/Logger folder, create a new class CustomLoggerProcessor.php with the following code.

namespace App\Logger;

/**
 * Class CustomLoggerProcessor
 */
class CustomLoggerProcessor
{
    /**
     * Transform the log message to custom format
     *
     * @param array $record
     *
     * @return array
     */
    public function __invoke(array $record)
    {
        return [
            'time' => $record['datetime']->format('Y-m-d H:i:s'),
            'level' => $record['level_name'] ?? "",
            'logger' => $record['channel'] ?? "",
            'message' => $record['message'] ?? "",
            'context' => $record['context'] ?? "",
        ];
    }
}

Here we are creating a new log format from the Monolog format. If its not required, you could just use the Monolog format itself.

3) Define the new Logging Channel

Add a new custom channel for your new CustomLoggerFactory

'channels' => [
    // other channels...
    
    'stdout' => [
        'driver' => 'custom',
        'via' => App\Logger\CustomLoggerFactory::class,
        'level' => env('LOG_LEVEL', 'debug'),
        'with' => [
            'stream' => 'php://stdout',
        ],
    ],
],

If you like to use the stdout as the default logging, then you need to set it up here as below,

    'default' => env('LOG_CHANNEL', 'stdout'),

You now have a created a custom logger for Laravel with custom logging format.

Spread the love
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments