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.