Files
ChatbotAI/app/Console/Commands/HealthCheckCommand.php
2026-05-18 08:56:23 +08:00

110 lines
4.9 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Console\Commands;
use App\Services\Ollama\OllamaService;
use App\Services\Qdrant\QdrantService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
/**
* php artisan kb:health-check
*
* Semak status semua perkhidmatan yang diperlukan.
*/
class HealthCheckCommand extends Command
{
protected $signature = 'kb:health-check';
protected $description = 'Semak status Ollama, Qdrant, dan MySQL';
public function handle(OllamaService $ollama, QdrantService $qdrant): int
{
$this->info('════════════════════════════════════════');
$this->info(' PEMERIKSAAN KESIHATAN SISTEM');
$this->info('════════════════════════════════════════');
$allOk = true;
// ── MySQL ─────────────────────────────────────────────────────────
$this->line('');
$this->info('📦 MySQL');
try {
DB::connection()->getPdo();
$dbName = DB::getDatabaseName();
$this->line(" ✅ Berjaya sambung ke: {$dbName}");
} catch (\Exception $e) {
$this->error(" ❌ Tidak dapat sambung: {$e->getMessage()}");
$allOk = false;
}
// ── Ollama ────────────────────────────────────────────────────────
$this->line('');
$this->info('🤖 Ollama');
$ollamaStatus = $ollama->healthCheck();
if ($ollamaStatus['online']) {
$this->line(" ✅ Online");
$chatOk = $ollamaStatus['chat_model'] ? '✅' : '❌';
$embedOk = $ollamaStatus['embed_model'] ? '✅' : '❌';
$this->line(" {$chatOk} Model Chat: " . config('ollama.chat_model'));
$this->line(" {$embedOk} Model Embed: " . config('ollama.embedding_model'));
if (!$ollamaStatus['chat_model'] || !$ollamaStatus['embed_model']) {
$allOk = false;
}
} else {
$this->error(" ❌ Offline");
if ($ollamaStatus['error']) {
$this->line(" " . $ollamaStatus['error']);
}
$allOk = false;
}
// ── Qdrant ────────────────────────────────────────────────────────
$this->line('');
$this->info('🗄️ Qdrant');
$qdrantStatus = $qdrant->healthCheck();
if ($qdrantStatus['online']) {
$this->line(" ✅ Online");
$collOk = $qdrantStatus['collection_exists'] ? '✅' : '⚠️ ';
$this->line(" {$collOk} Collection: " . config('qdrant.collection'));
if ($qdrantStatus['collection_exists']) {
$this->line(" 📊 Vectors: " . number_format($qdrantStatus['points_count'] ?? 0));
} else {
$this->warn(" Collection belum wujud. Akan dibuat secara automatik semasa pertama embed.");
}
} else {
$this->error(" ❌ Offline");
if ($qdrantStatus['error']) {
$this->line(" " . $qdrantStatus['error']);
}
$allOk = false;
}
// ── Queue ─────────────────────────────────────────────────────────
$this->line('');
$this->info('⏳ Queue');
$driver = config('queue.default');
$this->line(" Driver: {$driver}");
if ($driver === 'sync') {
$this->warn(" ⚠️ Queue driver adalah 'sync' — job akan dijalankan secara synchronous.");
$this->warn(" Tukar kepada 'database' atau 'redis' untuk production.");
} else {
$this->line(" ✅ Driver konfigurasi untuk async.");
}
// ── Ringkasan ─────────────────────────────────────────────────────
$this->line('');
$this->info('════════════════════════════════════════');
if ($allOk) {
$this->info(' ✅ SEMUA PERKHIDMATAN OK');
} else {
$this->error(' ❌ ADA PERKHIDMATAN YANG BERMASALAH');
}
$this->info('════════════════════════════════════════');
return $allOk ? self::SUCCESS : self::FAILURE;
}
}