$this->getScheduleStatus(), 'horizon' => $this->getHorizonStatus(), 'schedule_last_runtime' => Cache::get(CacheKey::get('SCHEDULE_LAST_CHECK_AT', null)), ]; return $this->success($data); } public function getQueueWorkload(WorkloadRepository $workload) { return $this->success(collect($workload->get())->sortBy('name')->values()->toArray()); } protected function getScheduleStatus(): bool { return (time() - 120) < Cache::get(CacheKey::get('SCHEDULE_LAST_CHECK_AT', null)); } protected function getHorizonStatus(): bool { if (!$masters = app(MasterSupervisorRepository::class)->all()) { return false; } return collect($masters)->contains(function ($master) { return $master->status === 'paused'; }) ? false : true; } public function getQueueStats() { $data = [ 'failedJobs' => app(JobRepository::class)->countRecentlyFailed(), 'jobsPerMinute' => app(MetricsRepository::class)->jobsProcessedPerMinute(), 'pausedMasters' => $this->totalPausedMasters(), 'periods' => [ 'failedJobs' => config('horizon.trim.recent_failed', config('horizon.trim.failed')), 'recentJobs' => config('horizon.trim.recent'), ], 'processes' => $this->totalProcessCount(), 'queueWithMaxRuntime' => app(MetricsRepository::class)->queueWithMaximumRuntime(), 'queueWithMaxThroughput' => app(MetricsRepository::class)->queueWithMaximumThroughput(), 'recentJobs' => app(JobRepository::class)->countRecent(), 'status' => $this->getHorizonStatus(), 'wait' => collect(app(WaitTimeCalculator::class)->calculate())->take(1), ]; return $this->success($data); } /** * Get the total process count across all supervisors. * * @return int */ protected function totalProcessCount() { $supervisors = app(SupervisorRepository::class)->all(); return collect($supervisors)->reduce(function ($carry, $supervisor) { return $carry + collect($supervisor->processes)->sum(); }, 0); } /** * Get the number of master supervisors that are currently paused. * * @return int */ protected function totalPausedMasters() { if (!$masters = app(MasterSupervisorRepository::class)->all()) { return 0; } return collect($masters)->filter(function ($master) { return $master->status === 'paused'; })->count(); } public function getAuditLog(Request $request) { $current = max(1, (int) $request->input('current', 1)); $pageSize = max(10, (int) $request->input('page_size', 10)); $builder = AdminAuditLog::with('admin:id,email') ->orderBy('id', 'DESC') ->when($request->input('action'), fn($q, $v) => $q->where('action', $v)) ->when($request->input('admin_id'), fn($q, $v) => $q->where('admin_id', $v)) ->when($request->input('keyword'), function ($q, $keyword) { $q->where(function ($q) use ($keyword) { $q->where('uri', 'like', '%' . $keyword . '%') ->orWhere('request_data', 'like', '%' . $keyword . '%'); }); }); $total = $builder->count(); $res = $builder->forPage($current, $pageSize)->get(); return response(['data' => $res, 'total' => $total]); } public function getHorizonFailedJobs(Request $request, JobRepository $jobRepository) { $current = max(1, (int) $request->input('current', 1)); $pageSize = max(10, (int) $request->input('page_size', 20)); $offset = ($current - 1) * $pageSize; $failedJobs = collect($jobRepository->getFailed()) ->sortByDesc('failed_at') ->slice($offset, $pageSize) ->values(); $total = $jobRepository->countFailed(); return response()->json([ 'data' => $failedJobs, 'total' => $total, 'current' => $current, 'page_size' => $pageSize, ]); } }