Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LARAVEL: Get an array of scheduled tasks for output in admin dashboard

Using the Laravel task scheduler I have created a number of tasks in Kernel.php

e.g:

$schedule->command('some:command')
    ->daily();

$schedule->command('another:command')
    ->daily();

I would like to display the list of scheduled commands and there frequency (as well as last/next run time, which I can log myself using the before/after functions).

However i'm stuck at the first hurdle. What i'm not sure how to do is get an array of the scheduled tasks that have been defined in Kernel.php

// Example function needs to be created
$tasks = getAllScheduledTasks();

@foreach($tasks as $task)
    <tr>
        <td>{{ $task->name }}</td>
        <td>{{ $task->description }}</td>
    </tr>
@endforeach

Simplified Question: How can I get an array of the scheduled tasks in Laravel?

like image 913
John Mellor Avatar asked Feb 22 '16 17:02

John Mellor


People also ask

How do I check my scheduled jobs in Laravel?

To monitor your schedule you should first run schedule-monitor:sync . This command will take a look at your schedule and create an entry for each task in the monitored_scheduled_tasks table. To view all monitored scheduled tasks, you can run schedule-monitor:list . This command will list all monitored scheduled tasks.

Which types of tasks can be scheduled with Laravel scheduler?

In addition to scheduling closures, you may also schedule Artisan commands and system commands. For example, you may use the command method to schedule an Artisan command using either the command's name or class.

How do I find a scheduled task?

To open Scheduled Tasks, click Start, click All Programs, point to Accessories, point to System Tools, and then click Scheduled Tasks. Use the Search option to search for "Schedule" and choose "Schedule Task" to open the Task Scheduler. Select the "Task Scheduler Library" to see a list of your Scheduled Tasks.

How do I know if Laravel Task Scheduler is running?

Well one of the way can test if Schedule is running you can dump anything to log file. Log::info('Schedule Running '. \Carbon\Carbon::now()); After that you can grep the message from Logs.


4 Answers

There's actually no support out of the box for this, unfortunately. What you'll have to do is extend the artisan schedule command and add a list feature. Thankfully there's a simple class you can run:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Console\Scheduling\Schedule;

class ScheduleList extends Command
{
    protected $signature = 'schedule:list';
    protected $description = 'List when scheduled commands are executed.';

    /**
     * @var Schedule
     */
    protected $schedule;

    /**
     * ScheduleList constructor.
     *
     * @param Schedule $schedule
     */
    public function __construct(Schedule $schedule)
    {
        parent::__construct();

        $this->schedule = $schedule;
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $events = array_map(function ($event) {
            return [
                'cron' => $event->expression,
                'command' => static::fixupCommand($event->command),
            ];
        }, $this->schedule->events());

        $this->table(
            ['Cron', 'Command'],
            $events
        );
    }

    /**
     * If it's an artisan command, strip off the PHP
     *
     * @param $command
     * @return string
     */
    protected static function fixupCommand($command)
    {
        $parts = explode(' ', $command);
        if (count($parts) > 2 && $parts[1] === "'artisan'") {
            array_shift($parts);
        }

        return implode(' ', $parts);
    }
}

This will provide you with a php artisan schedule:list. Now that's not exactly what you need, but then you can easily get this list from within your Laravel stack by executing:

Artisan::call('schedule:list');

And that will provide you with a list of the schedule commands.

Of course, don't forget to inject the Facade: use Illuminate\Support\Facades\Artisan;

like image 56
Ohgodwhy Avatar answered Oct 30 '22 21:10

Ohgodwhy


In case anyone is like me and is trying to do this in 2021. Based on old answers and a bit of playing around.

In Laravel Framework 8.22.1 I got to work by making app/Console/Kernel->schedule method public and then in a Controller:

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Events\Dispatcher;

    private function getScheduledJobs()
    {
        new \App\Console\Kernel(app(), new Dispatcher());
        $schedule = app(Schedule::class);
        $scheduledCommands = collect($schedule->events());

        return $scheduledCommands;
    }

Hope this saves time for future googlers like myself.

like image 40
Tautvydas Bagdžius Avatar answered Oct 30 '22 20:10

Tautvydas Bagdžius


As your not running through the console you need to invoke the schedule method on the Kernel in your controller... (don't forget to make the schedule method public instead of protected).

public function index(\Illuminate\Contracts\Console\Kernel $kernel, \Illuminate\Console\Scheduling\Schedule $schedule)
{
    $kernel->schedule($schedule);
    dd($schedule->events());
}
like image 43
fire Avatar answered Oct 30 '22 19:10

fire


I was having the task to stop/enable and edit the frequency of the scheduled tasks from the admin dashboard. So I foreach them in Kernel.php and capture the output in function.

$enabled_commands = ConsoleCommand::where('is_enabled', 1)
        ->get();

    foreach ($enabled_commands as $command)
    {
        $schedule->command($command->command_name)
            ->{$command->frequency}($command->time)
            ->after(function () use ($command) {
                $this->log($command->command_name);
            });
    }

Hope this help you.

like image 32
Martin Tonev Avatar answered Oct 30 '22 21:10

Martin Tonev