While experimenting, I was able to achieve this behavior by writing my own Monolog handler:
- It seems this can be done with generic
debug_backtrace(), but I liked the package:
composer require spatie/backtrace
- app\Logging\SourceClassAwareHandler.php
<?php
namespace App\Logging;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\LogRecord;
use Spatie\Backtrace\Backtrace;
class SourceClassAwareHandler extends AbstractProcessingHandler
{
public function write(LogRecord $record): void
{
$frames = Backtrace::create()->frames();
$offset = 8; /* you should pick this value with an experiment, it depends on backtrace content */
$class = $frames[$offset]->class;
$log_file = match ($class) {
\App\Console\Commands\TestCommand::class => 'command.log',
\App\Console\Commands\MyCommand::class => 'my.log',
\App\Jobs\TestJob::class => 'job.log',
default => 'laravel.log',
};
file_put_contents(storage_path('logs/' . $log_file), $record->formatted, FILE_APPEND);
}
}
- config/logging.php
'channels' => [
'class-aware-logger' => [
'driver' => 'monolog',
'handler' => \App\Logging\SourceClassAwareHandler::class,
],
],
- .env
LOG_CHANNEL=class-aware-logger
Now if I call this inside \App\Jobs\TestJob class:
Log::info("log data from TestJob class");
the following log entry appears in 'job.log' file:
[2025-05-03 01:58:59] local.INFO: log data from TestJob class
Honestly, I don't really like the solution, but it works as I want it to work. Any ideas how to make it more elegant way?