Changing log file path dynamically when running laravel task scheduler

54 views Asked by At

In app\Console\Kernel.php, I have two commands.

protected function schedule(Schedule $schedule)
{
    $schedule->command("cron:batch-1")
            ->name("batch-1")
            ->everyMinute()
            ->runInBackground()
            ->withoutOverlapping()
            ->onFailure(function () {
                Log::channel('cronlog')->error("cron:batch-1 is fail at" . Carbon::now());
            });
    $schedule->command("cron:batch-2")
            ->name("batch-2")
            ->everyMinute()
            ->runInBackground()
            ->withoutOverlapping()
            ->onFailure(function () {
                Log::channel('cronlog')->error("cron:batch-2 is fail at" . Carbon::now());
            });
}

Inside batch-1 command, following code is exists.

public function handle()
{   
    // Get tenant id
    $tenants = Tenant::all;
    foreach($tenants as $tenant) {
        // clear cache to separate log
        Artisan::call("config:cache");
        $currentTenant = Tenant::find($tenant);
        $this->closeApplication($currentTenant);
    }
}

public function closeApplication($tenant)
{
    // load multitenancy
    $tenant->configure()->use();
    // change log file path based on tenant
    (new Tenancy())->configureLogFile();
    // other logic code ...
    Log::channel("cronlog")->info("[{$tenant->customer_name}] batch-1 command is running.");
}

Here is batch-2 command code.

public function handle()
{   
    // Get tenant id
    $tenants = Tenant::all;
    foreach($tenants as $tenant) {
        // clear cache to separate log
        Artisan::call("config:cache");
        $currentTenant = Tenant::find($tenant);
        $this->openApplication($currentTenant);
    }
}

public function openApplication($tenant)
{
    // load multitenancy
    $tenant->configure()->use();
    // change log file path based on tenant
    (new Tenancy())->configureLogFile();
    
    Log::channel("cronlog")->info("[{$tenant->customer_name}] batch-2 command is running.");
}

Both of the code is nearly the same. You will see (new Tenancy())->configureLogFile(); inside both code is to separate log file per tenant. Here is what I want to separate log file like following.

for tenant-1 => storage/logs/tenant-1/tenant-1_cronlog_{date}.log
for tenant-2 => storage/logs/tenant-2/tenant-2_cronlog_{date}.log

Here is the configureLogFile() method.

public function configureLogFile()
{
    // get current tenant key name
    $currentTenant = (new Tenant())->currentTenantKeyName();
    $customerKeyName = $currentTenant ?? null;
    $directory = $customerKeyName . '/';
    // get channel key as array data
    $channels = array_keys(config('logging.channels'));
    // loop all channel
    foreach($channels as $channel) {
        // if new channel is created by developer, we will use channel name as log file name
        // eg: for `customlog` channel, file name will be `keyname_customlog.log`
        $filePath = storage_path('logs/' . $directory . $customerKeyName . '_'.$channel.'.log');
        config(['logging.channels.'.$channel.'.path' => $filePath]);
    }
}

This code is changing log file path based on tenant with config() helper.

First problem is, if I remove Artisan::call("config:cache"); from both command(batch-1, batch-2), log file is not separate per tenant. Subsequent tenant-2, tenant-3 logs are written into tenant-1 log file. Which is why I add Artisan::call("config:cache"); in both command.

Second problem is, when I add Artisan::call("config:cache"); in both command and these two commands are running at every minute(same time), I got following error.

Argument 2 passed to Facade\Ignition\QueryRecorder\QueryRecorder::__construct() must be of the type bool, null given, called in C:\laragon\www\api-career\vendor\facade\ignition\src\IgnitionServiceProvider.php on line 386 {"exception":"[object] (TypeError(code: 0): Argument 2 passed to Facade\\Ignition\\QueryRecorder\\QueryRecorder::__construct() must be of the type bool, null given, called in ...

When this error occur, commands are misbehaving. batch-1 or batch-2 cron is not running anymore. After I search why this error occur, I found it because of calling "config:cache". But, I'm not yet know how to solve. All I want is to separate log file per tenant. I have tried a lot of way like followig link, but it is not working.

Custom (dynamic) log file names with laravel5.6

Laravel 7 set log path dynamically in Job class

0

There are 0 answers