Monitoring Laravel yang benar-benar kepakai saat ada masalah
Monitoring aplikasi Laravel bukan sekadar melihat server masih hidup. Yang perlu dijaga adalah alur kerja pentingnya: request web masuk, API merespons, queue tetap mengolah pekerjaan, dan scheduler tidak diam-diam berhenti. Kalau salah satu putus, biasanya baru ketahuan setelah ada pengguna komplain atau laporan tidak terkirim.
Tutorial ini memakai kombinasi log Laravel, Laravel Horizon untuk queue Redis, cron untuk scheduler, dan endpoint health check untuk dipantau dari luar. Susunannya cukup aman untuk aplikasi kecil sampai aplikasi produksi yang mulai ramai.

Prasyarat
- Aplikasi Laravel sudah berjalan di server Linux.
- Akses SSH dan hak untuk mengatur cron atau Supervisor/systemd.
- Redis tersedia bila queue akan dipantau memakai Laravel Horizon.
- Composer dan PHP CLI sesuai kebutuhan proyek.
- Alat pemantau URL dari luar, misalnya Uptime Kuma, layanan monitoring internal, atau platform sejenis.
Langkah 1: Rapikan log dan pastikan konfigurasi produksi masuk akal
Mulai dari hal dasar. Log adalah tempat pertama yang dibuka saat pekerjaan queue gagal atau endpoint API menghasilkan 500. Di file .env, pastikan mode produksi tidak menampilkan detail error ke pengguna, tetapi error tetap dicatat.
APP_ENV=production
APP_DEBUG=false
LOG_CHANNEL=stack
LOG_LEVEL=infoSetelah mengubah konfigurasi, bersihkan cache agar Laravel tidak memakai nilai lama.

php artisan optimize:clear
php artisan config:cacheJangan menjadikan log sebagai satu-satunya alarm. Log bagus untuk investigasi, tetapi tidak akan membangunkan operator ketika scheduler berhenti. Tetap perlu pemeriksaan aktif dari luar.
Langkah 2: Buat endpoint health check aplikasi dan API
Health check yang sederhana memberi jawaban cepat: apakah Laravel bisa menerima request dan membalas respons. Di Laravel versi baru, endpoint /up biasanya sudah tersedia. Jika belum ada atau Anda ingin endpoint sendiri, tambahkan di routes/web.php.
use Illuminate\Support\Facades\Route;
Route::get('/health', function () {
return response()->json([
'status' => 'ok',
'time' => now()->toIso8601String(),
]);
});Untuk API, lebih berguna memantau endpoint yang mewakili alur nyata, misalnya endpoint autentikasi, katalog, atau data master. Hindari endpoint yang terlalu berat. Tujuannya mendeteksi gangguan, bukan menambah beban server setiap satu menit.
Kalau endpoint ini dibuka ke internet, jangan masukkan informasi sensitif seperti versi PHP, nama database, atau isi konfigurasi. Status singkat sudah cukup. Bila perlu, batasi akses health check dengan IP monitoring atau token di level web server.
Langkah 3: Pantau queue dengan Laravel Horizon
Jika driver queue Anda Redis, Horizon adalah pilihan praktis karena memperlihatkan antrean aktif, job gagal, throughput, dan worker. Ini jauh lebih enak daripada menebak-nebak dari log.
- Pasang Horizon di proyek Laravel.
- Publikasikan konfigurasi dan migrasi bawaan.
- Jalankan worker Horizon sebagai layanan permanen.
composer require laravel/horizon
php artisan horizon:install
php artisan migrateAtur jumlah proses dan queue yang diproses di config/horizon.php. Untuk awal, pisahkan pekerjaan cepat dan berat bila memang ada. Contohnya, email dan notifikasi bisa di queue default, sedangkan ekspor laporan di queue reports. Pemisahan ini mencegah ekspor besar membuat notifikasi penting ikut terlambat.
Daftarkan Horizon ke Supervisor agar otomatis hidup lagi setelah proses mati atau server reboot.
[program:laravel-horizon]
process_name=%(program_name)s
command=php /var/www/aplikasi/artisan horizon
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/var/www/aplikasi/storage/logs/horizon.log
stopwaitsecs=3600Sesuaikan path proyek dan user server. Lalu muat ulang konfigurasi Supervisor.
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-horizonDashboard Horizon umumnya tersedia di /horizon. Jangan biarkan URL ini terbuka bebas di produksi; atur otorisasi pada HorizonServiceProvider atau lindungi lewat jaringan internal.
Langkah 4: Catat dan beri alarm untuk job yang gagal
Job gagal sering kali tidak langsung terlihat, terutama jika queue masih berjalan normal. Aktifkan tabel failed jobs supaya ada jejak yang bisa diperiksa dan diulang setelah penyebabnya dibereskan.
php artisan queue:failed-table
php artisan migrate
php artisan queue:failedJangan langsung menjalankan queue:retry all tanpa membaca error. Kalau masalahnya kredensial API kedaluwarsa atau data input rusak, retry massal hanya membuat error menumpuk lagi. Periksa satu contoh job gagal, perbaiki akar masalahnya, baru ulangi job yang relevan.
Langkah 5: Jalankan scheduler lewat cron
Laravel scheduler hanya akan bekerja jika schedule:run dipanggil setiap menit. Ini bagian yang paling sering terlewat setelah deployment server baru.
Buka crontab milik user yang menjalankan aplikasi, lalu tambahkan baris berikut.
* * * * * cd /var/www/aplikasi && php artisan schedule:run >> /dev/null 2>&1Gunakan path absolut bila lingkungan cron berbeda dengan shell SSH. Cron sering tidak memuat PATH, versi PHP, atau environment yang biasa dipakai saat login. Kalau ada beberapa versi PHP, tuliskan lokasi binary secara eksplisit, misalnya /usr/bin/php8.3.
Untuk memastikan scheduler benar-benar punya tugas, lihat daftar schedule yang terdaftar.
php artisan schedule:listLangkah 6: Buat tanda hidup scheduler
Cron bisa saja aktif, tetapi command di dalam scheduler gagal karena koneksi database atau konfigurasi aplikasi. Karena itu, buat tanda hidup yang bisa diperiksa. Salah satu cara sederhana adalah menyimpan waktu eksekusi terakhir ke cache atau database dari scheduled task penting.
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schedule;
Schedule::call(function () {
Cache::put('scheduler:last_run', now()->toIso8601String(), now()->addMinutes(10));
})->everyMinute();Lalu tampilkan nilai tersebut di endpoint internal atau periksa lewat Tinker. Jika nilainya lebih tua dari beberapa menit, anggap scheduler bermasalah dan kirim alarm. Batas waktunya sesuaikan dengan toleransi operasional aplikasi; untuk proses laporan harian, lima belas menit mungkin masih aman, untuk pembayaran jelas tidak.
Langkah 7: Atur pemantauan dari luar server
Tambahkan monitor HTTP ke /health dan endpoint API penting. Interval satu sampai lima menit biasanya cukup untuk aplikasi biasa. Aktifkan notifikasi ke kanal yang benar-benar dibaca tim, misalnya email, Telegram, Slack, atau sistem tiket internal.
Untuk queue dan scheduler, buat pemeriksaan tambahan. Bisa berupa skrip yang mengecek worker Horizon, jumlah failed jobs, umur job tertua, serta nilai scheduler:last_run. Alarm yang bagus menyebutkan masalahnya dengan jelas, misalnya “scheduler tidak update selama 10 menit”, bukan sekadar “server error”.
Cara cek hasil
- Buka
/healthdan pastikan respons JSON berstatus 200. - Buka dashboard Horizon, lalu kirim satu job uji dan lihat apakah job selesai diproses.
- Jalankan
php artisan schedule:runsecara manual untuk memastikan task scheduler tidak error. - Tunggu dua sampai tiga menit, lalu cek apakah nilai tanda hidup scheduler berubah.
- Uji alarm dengan menghentikan worker di lingkungan staging atau dengan monitor uji. Jangan menguji dengan mematikan layanan produksi tanpa prosedur yang jelas.
Kalau masih gagal
Queue tidak bergerak
Cek status Supervisor dengan sudo supervisorctl status, lalu lihat storage/logs/horizon.log dan log Laravel. Pastikan Redis bisa diakses dan variabel QUEUE_CONNECTION sudah sesuai. Sering kali masalahnya sesederhana worker masih membaca konfigurasi lama setelah deployment; jalankan php artisan horizon:terminate agar Supervisor memulai proses baru.
Scheduler tidak jalan
Pastikan cron terpasang pada user yang tepat dengan crontab -l. Cek log cron sistem dan coba command cron secara manual dari user yang sama. Bila command bekerja di SSH tetapi gagal di cron, biasanya penyebabnya PATH, binary PHP, permission folder storage, atau file .env yang tidak terbaca.
Health check selalu gagal
Uji dari server memakai curl -i https://domain-anda/health, lalu bandingkan dengan hasil dari luar jaringan. Kalau internal berhasil tetapi monitor eksternal gagal, periksa DNS, firewall, SSL, reverse proxy, atau aturan WAF. Jangan buru-buru mengubah kode Laravel sebelum jalur jaringan diperiksa.
Tips operasional
- Bedakan alarm kritis dan peringatan. Queue email terlambat lima menit mungkin peringatan; job pembayaran gagal adalah alarm kritis.
- Simpan log dengan rotasi yang jelas. Disk penuh karena log juga bisa membuat aplikasi terlihat “aneh” dan sulit didiagnosis.
- Masukkan pengecekan queue, scheduler, dan endpoint API ke checklist setelah deployment.
- Catat siapa yang menerima alarm dan apa langkah pertama yang harus dilakukan. Alarm tanpa pemilik biasanya hanya jadi kebisingan.
- Uji skenario gagal secara berkala di staging. Monitoring yang belum pernah diuji sering baru ketahuan cacat ketika insiden terjadi.
Penutup
Monitoring Laravel yang sehat tidak perlu langsung rumit. Mulai dari health check, Horizon, cron yang benar, dan alarm untuk failed job maupun scheduler yang mandek. Setelah itu, lihat pola gangguan yang benar-benar terjadi di aplikasi Anda. Dari sana, baru tambah metrik atau integrasi yang memang membantu operasi harian, bukan sekadar membuat dashboard terlihat ramai.