Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

stratboy's avatar

How to log something from objects used in Task Schedules?

Hi, I'm experimenting with Task Schedules, and doing something very easy:

Schedule::call(function () {
     // Using full class path here because of conflicts with the Intervention class
     App\Models\Image::whereDoesntHaveMorph('imageable', [Seed::class])->delete();
})->everyMinute();

And that works (deletes the orphan records). But then, the Image model should also delete the image files on an AS3 disk (please see below). But the images do not get deleted, and there are no error logs on storage/laravel.log, nor I see logs written by me with my lg() helper (which I always use everywhere). Why? How to? How can I debug functions called by a schedule?

    protected static function boot(){
        parent::boot();

		// this is to delete image files after deleting the records
        static::deleted(function ($model) {
            // this is an helper function that I made that logs to a custom storage/debug.log
            // it usually works properly
            lg('deleted',$model); // doesn't log anything
            $model->delete_image_sizes();
        });
    }

and then:

    private function delete_image_sizes(){
        $file_name = $this->data; // image-name.jpg
        
        // original
        $file_path = 'images/' . $file_name;
        $response = Storage::disk('s3')->delete($file_path);

        lg('', $response);
        lg('', $file_path);

        // thumb
        // $micro_image_name = Str::replaceLast('.', '-micro.', $file_name);
        // $micro_image_path = 'images/' . $micro_image_name;
        // Storage::disk('s3')->delete($micro_image_path);
    }
0 likes
6 replies
LaryAI's avatar
Level 58

To debug and ensure that your scheduled task is working correctly, including logging and deleting image files, you can follow these steps:

  1. Ensure Logging is Working: First, verify that your lg() helper function is working correctly outside of the scheduled task. You can do this by calling it directly in a route or controller.

  2. Check Task Schedule Execution: Ensure that your task schedule is being executed. You can do this by adding a simple log statement at the beginning of the scheduled function.

  3. Check Model Events: Ensure that the model events are being triggered correctly. You can add log statements in the deleted event to verify this.

  4. Check Storage Disk Configuration: Ensure that your S3 disk configuration is correct and that you have the necessary permissions to delete files.

Here is an updated version of your code with additional logging to help you debug the issue:

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use App\Models\Image;
use App\Models\Seed;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Schedule;

// Schedule the task
Schedule::call(function () {
    Log::info('Scheduled task started');
    Image::whereDoesntHaveMorph('imageable', [Seed::class])->delete();
    Log::info('Scheduled task completed');
})->everyMinute();

// In your Image model
protected static function boot(){
    parent::boot();

    // this is to delete image files after deleting the records
    static::deleted(function ($model) {
        Log::info('Image model deleted event triggered', ['model' => $model]);
        lg('deleted', $model); // custom log function
        $model->delete_image_sizes();
    });
}

private function delete_image_sizes(){
    $file_name = $this->data; // image-name.jpg
    
    // original
    $file_path = 'images/' . $file_name;
    $response = Storage::disk('s3')->delete($file_path);

    Log::info('Deleting original image', ['file_path' => $file_path, 'response' => $response]);
    lg('', $response);
    lg('', $file_path);

    // thumb
    // $micro_image_name = Str::replaceLast('.', '-micro.', $file_name);
    // $micro_image_path = 'images/' . $micro_image_name;
    // Storage::disk('s3')->delete($micro_image_path);
}

Steps to Debug:

  1. Check Laravel Logs: Look at the storage/logs/laravel.log file to see if the log statements are being written. This will help you determine if the scheduled task is running and if the model events are being triggered.

  2. Check Custom Logs: Ensure that your lg() helper function is writing to the correct log file. You can add a simple test log statement in a route or controller to verify this.

  3. Check S3 Configuration: Ensure that your S3 disk configuration in config/filesystems.php is correct and that you have the necessary permissions to delete files.

  4. Run Scheduler Manually: You can run the scheduler manually using the following Artisan command to see if there are any errors:

    php artisan schedule:run
    

By following these steps and adding the additional logging, you should be able to identify where the issue lies and ensure that your scheduled task is working correctly.

stratboy's avatar

Lary's suggestions do not work becouse I was already doing all that.

martinbean's avatar

@stratboy Events won’t be fired because you’re doing a mass query. Events are only fired for single model instances.

There’s a note in the Eloquent event docs on this:

When issuing a mass update or delete query via Eloquent, the saved, updated, deleting, and deleted model events will not be dispatched for the affected models. This is because the models are never actually retrieved when performing mass updates or deletes.

stratboy's avatar

@martinbean ok thank you. So to use events I should loop through the collection, I guess. Being it a cron job I will trigger once a day, I think it's not a problem.. Or is there any other better way of deleting files when deleting corresponding records?

martinbean's avatar

@stratboy If you want events to be emitted then yes, you need to retrieve the models and then call delete on each instance. Whether this is a good idea or not, I don’t know, as I don‘t know how many records you’re looking to query and delete.

Snapey's avatar

@stratboy you are going to have to have a collection of models at some point, just to get the filenames.

Image::whereDoesntHaveMorph('imageable', [Seed::class])
	->each(function($image){
		// delete S3
		// delete the model
	}};

Please or to participate in this conversation.