53 خطوط
2.0 KiB
PHP
53 خطوط
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\System\Http;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Modules\System\Domain\DeploymentCapabilities;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Throwable;
|
|
|
|
final class SystemHealthController extends Controller
|
|
{
|
|
public function __invoke(DeploymentCapabilities $deployment): JsonResponse
|
|
{
|
|
$database = $this->probe(fn () => DB::select('select 1'));
|
|
$storage = $this->probe(function (): void {
|
|
$path = 'health/'.gethostname().'.probe';
|
|
Storage::disk(config('filesystems.default'))->put($path, now()->toISOString());
|
|
Storage::disk(config('filesystems.default'))->delete($path);
|
|
});
|
|
$heartbeat = Cache::get('system:scheduler-heartbeat');
|
|
$queueHeartbeat = Cache::get('system:queue-heartbeat');
|
|
$queue = config('queue.default') === 'sync'
|
|
? 'local'
|
|
: ($queueHeartbeat && now()->diffInMinutes($queueHeartbeat) < 3 ? 'ok' : 'degraded');
|
|
$services = [
|
|
'api' => 'ok', 'database' => $database, 'storage' => $storage,
|
|
'queue' => $queue,
|
|
'scheduler' => $heartbeat && now()->diffInMinutes($heartbeat) < 3 ? 'ok' : 'degraded',
|
|
'mail' => config('mail.default') === 'log' ? 'local' : 'configured',
|
|
'websocket' => config('broadcasting.default') === 'log' ? 'degraded' : 'configured',
|
|
'exportWorker' => $queue,
|
|
'aiProvider' => config('ai.provider', 'local-structuring'),
|
|
];
|
|
$ok = $database === 'ok' && $storage === 'ok';
|
|
|
|
return response()->json(['data' => ['status' => $ok ? 'ok' : 'degraded', 'deploymentMode' => $deployment->mode()->value, 'services' => $services, 'checkedAt' => now()->toISOString()]], $ok ? 200 : 503);
|
|
}
|
|
|
|
private function probe(callable $callback): string
|
|
{
|
|
try {
|
|
$callback();
|
|
|
|
return 'ok';
|
|
} catch (Throwable) {
|
|
return 'failed';
|
|
}
|
|
}
|
|
}
|