diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 80b09d2ee..b4c0a1af3 100755 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -6,11 +6,22 @@ use App\Console\Cron\Monthly; use App\Console\Cron\Nightly; use App\Console\Cron\Weekly; +use App\Services\CronService; use Illuminate\Console\Scheduling\Schedule; +use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Contracts\Foundation\Application; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { + private $cronSvc; + + public function __construct(Application $app, Dispatcher $events) + { + parent::__construct($app, $events); + $this->cronSvc = app(CronService::class); + } + /** * Define the application's command schedule. * @@ -28,6 +39,9 @@ protected function schedule(Schedule $schedule): void // When spatie-backups runs $schedule->command('backup:clean')->daily()->at('01:00'); $schedule->command('backup:run')->daily()->at('02:00'); + + // Update the last time the cron was run + $this->cronSvc->updateLastRunTime(); } /** diff --git a/app/Http/Controllers/Admin/MaintenanceController.php b/app/Http/Controllers/Admin/MaintenanceController.php index 94d3c638b..033500b43 100644 --- a/app/Http/Controllers/Admin/MaintenanceController.php +++ b/app/Http/Controllers/Admin/MaintenanceController.php @@ -3,19 +3,33 @@ namespace App\Http\Controllers\Admin; use App\Contracts\Controller; +use App\Services\CronService; use Illuminate\Http\Request; use Illuminate\Support\Facades\Artisan; use Laracasts\Flash\Flash; class MaintenanceController extends Controller { - public function __construct() + private $cronSvc; + + public function __construct(CronService $cronSvc) { + $this->cronSvc = $cronSvc; } public function index() { - return view('admin.maintenance.index'); + // Generate the cron path. Replace php-fpm with just php + $cron_path = [ + '* * * * *', + $this->cronSvc->getCronPath(), + '>> /dev/null 2>&1', + ]; + + return view('admin.maintenance.index', [ + 'cron_path' => implode(' ', $cron_path), + 'cron_problem_exists' => $this->cronSvc->cronProblemExists(), + ]); } /** diff --git a/app/Services/CronService.php b/app/Services/CronService.php new file mode 100644 index 000000000..c6de36bff --- /dev/null +++ b/app/Services/CronService.php @@ -0,0 +1,73 @@ +kvpRepo = $kvpRepo; + } + + /** + * Get the path for running a cron job + * + * @return string + */ + public function getCronPath(): string + { + $path = [ + 'cd '.base_path(), + '&&', + str_replace('-fpm', '', PHP_BINARY), + 'artisan schedule:run', + ]; + + return implode(' ', $path); + } + + /** + * Update the last time the cron was run in the kvp repo + */ + public function updateLastRunTime() + { + $dt = new DateTime('now', DateTimeZone::UTC); + $this->kvpRepo->save('cron_last_run', $dt->format(DateTime::ISO8601)); + } + + /** + * True/false if there's a problem with the cron. Now this is mainly + * if the cron hasn't run in the last 5 minutes at least + * + * @return bool + */ + public function cronProblemExists(): bool + { + $last_run = $this->kvpRepo->get('cron_last_run'); + if (empty($last_run)) { + return true; + } + + try { + $dt = DateTime::createFromFormat(DateTime::ISO8601, $last_run); + $dt_now = new DateTime('now', DateTimeZone::UTC); + } catch (Exception $e) { + Log::error('Error checking for cron problem: '.$e->getMessage()); + return true; + } + + // More than 5 minutes... there's a problem + $diff = $dt_now->diff($dt); + return $diff->i > 5; + } +} diff --git a/resources/views/admin/maintenance/caches.blade.php b/resources/views/admin/maintenance/caches.blade.php index ecf893b8d..bfb5a01d1 100644 --- a/resources/views/admin/maintenance/caches.blade.php +++ b/resources/views/admin/maintenance/caches.blade.php @@ -4,7 +4,7 @@
A cron must be created that runs every minute calling artisan. Example:
+ + + @if($cron_problem_exists) +