Monitoring Laravel di Production: Dari HTTP Request sampai Database, Queue, Redis, dan Server
Monitoring Laravel di Production: Dari HTTP Request sampai Database, Queue, Redis, dan Server
Ringkasan
Aplikasi Laravel yang sudah masuk production tidak cukup hanya dipastikan "masih bisa diakses". Dalam kondisi nyata, aplikasi bisa saja tetap mengembalikan HTTP 200, tetapi response time sudah memburuk, database mulai kehabisan connection, queue menumpuk, Redis kehabisan memory, disk hampir penuh, atau worker PHP-FPM sudah terlalu banyak menunggu.
Di sinilah monitoring menjadi penting.
Monitoring production bukan sekadar membuka dashboard CPU dan RAM. Kita perlu melihat kondisi aplikasi dari beberapa lapisan: HTTP request, Laravel, database, Redis, queue, scheduler, PHP-FPM, Nginx, operating system, sampai jaringan. Untuk sistem yang lebih matang, semua data tersebut kemudian dikumpulkan menjadi observability yang menggabungkan metrics, logs, traces, dan kadang profiling sehingga masalah bisa ditelusuri dari gejalanya sampai penyebabnya.
Artikel ini membahas cara membangun monitoring Laravel production secara bertahap, mulai dari server VPS sederhana sampai arsitektur yang lebih lengkap menggunakan Laravel Pulse, Horizon, Prometheus, Grafana, Loki, OpenTelemetry, dan tools pendukung lainnya.
1. Kenapa Monitoring Laravel di Production Itu Penting?
Saat aplikasi masih dikerjakan di local, biasanya developer cukup melakukan:
php artisan serve
Lalu ketika ada error, tinggal melihat terminal.
Production jelas berbeda.
Bayangkan sebuah aplikasi Laravel digunakan oleh 500 pengguna setiap hari. Tiba-tiba pada jam 10 pagi pengguna mengeluh:
"Halaman dashboard lama sekali."
Masalahnya bisa berasal dari banyak tempat.
Mungkin:
query PostgreSQL lambat;
terlalu banyak query dalam satu request;
index database tidak digunakan;
Redis sedang penuh;
API external sedang lambat;
PHP-FPM kekurangan worker;
server kehabisan memory;
disk hampir penuh;
queue worker mati;
network latency meningkat;
deployment baru memperkenalkan bug;
atau aplikasi sebenarnya sehat, tetapi traffic meningkat drastis.
Kalau kita hanya melihat:
top
kita mungkin melihat CPU 50%.
Lalu kita berpikir:
"Server masih aman."
Padahal request tertentu mungkin membutuhkan 5 detik.
Artinya, resource server tidak selalu menggambarkan pengalaman pengguna.
Inilah alasan monitoring production harus melihat sistem dari beberapa perspektif sekaligus.
2. Monitoring, Logging, Observability: Apa Bedanya?
Tiga istilah ini sering dianggap sama.
Sebenarnya ada perbedaan.
Monitoring
Monitoring menjawab:
"Apakah sistem sedang sehat?"
Contohnya:
CPU 72%;
memory 80%;
HTTP 500 meningkat;
request latency p95 = 1.8 detik;
database connections = 95%;
queue backlog = 10.000 jobs.
Biasanya monitoring sangat dekat dengan metrics.
Logging
Logging menjawab:
"Apa yang sebenarnya terjadi?"
Contohnya:
PaymentService failed to create payment
user_id=12345
order_id=ORD-2026-00921
exception=ConnectionTimeout
Log memberikan detail kejadian.
Observability
Observability lebih luas.
Pertanyaan yang ingin dijawab adalah:
"Dari data yang kita punya, apakah kita bisa memahami kenapa sistem berperilaku seperti ini?"
Biasanya observability menggunakan beberapa telemetry signal:
Metrics
Logs
Traces
Profiles
Grafana sendiri menjelaskan metrics sebagai gambaran kuantitatif kondisi sistem, logs sebagai detail kejadian, dan traces sebagai cara mengikuti alur aktivitas antar komponen.
Contohnya:
User
↓
Nginx
↓
Laravel
↓
PostgreSQL
↓
Redis
↓
External Payment API
Monitoring mungkin memberi tahu:
HTTP latency meningkat
Tracing dapat membantu menunjukkan:
Laravel request = 2.4 sec
PostgreSQL = 1.6 sec
Redis = 20 ms
Payment API = 600 ms
Laravel processing = 180 ms
Sekarang kita tahu bagian mana yang bermasalah.
Itulah perbedaan besar antara sekadar monitoring dan observability.
3. Prinsip Dasar Monitoring Production
Sebelum membahas tools, ada satu konsep yang menurut saya penting:
Jangan monitor tool. Monitor behavior dari sistem.
Misalnya kita memasang Prometheus, Grafana, Loki, dan OpenTelemetry.
Itu belum otomatis berarti sistem kita sudah termonitor dengan baik.
Yang perlu diketahui adalah:
Apakah user bisa mengakses aplikasi?
Apakah request mulai lambat?
Apakah error meningkat?
Apakah database mulai menjadi bottleneck?
Apakah queue tertinggal?
Apakah worker mati?
Apakah Redis kehabisan memory?
Apakah server kehabisan disk?
Apakah deployment baru menyebabkan masalah?
Jadi monitoring harus dimulai dari pertanyaan operasional, bukan dari daftar tools.
4. Lapisan Apa Saja yang Perlu Dimonitor?
Untuk aplikasi Laravel di production, saya biasanya membaginya menjadi beberapa layer.
┌──────────────────────┐
│ User │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ DNS / CDN / LB │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Nginx │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ PHP-FPM │
└──────────┬───────────┘
│
▼
┌──────────────────────┐
│ Laravel │
└──────┬───────┬───────┘
│ │
┌──────┘ └──────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ PostgreSQL │ │ Redis │
└─────────────┘ └──────┬──────┘
│
▼
┌──────────────┐
│ Queue Worker │
└──────────────┘
Masing-masing layer punya masalah dan metrics yang berbeda.
5. Layer Pertama: Monitoring dari Sisi User
Sebelum masuk ke Laravel, kita perlu tahu:
"Apakah aplikasi dapat diakses dari internet?"
Ini biasanya disebut uptime monitoring.
Contohnya menggunakan:
UptimeRobot
Better Stack
Pingdom
Grafana Cloud
Cloudflare
atau service monitoring lainnya.
Yang diperiksa biasanya:
GET https://example.com
Kemudian kita melihat:
HTTP Status
Response Time
Availability
SSL expiration
DNS
Misalnya:
Availability: 99.98%
Average response time: 420 ms
P95 response time: 1.2 s
HTTP errors: 0.8%
Ini penting karena server kita bisa saja sehat menurut internal monitoring, tetapi dari internet ternyata aplikasi tidak bisa diakses.
6. Laravel Health Check
Laravel sudah menyediakan health route.
Secara default endpoint-nya adalah:
/up
Endpoint ini mengembalikan HTTP 200 ketika aplikasi berhasil boot tanpa exception, dan 500 ketika boot gagal. Laravel juga menyediakan event DiagnosingHealth sehingga kita dapat menambahkan pemeriksaan seperti database dan cache.
Misalnya:
curl https://example.com/up
Response:
200 OK
Kemudian endpoint ini dapat dipakai oleh:
uptime monitor;
load balancer;
Kubernetes;
reverse proxy;
atau internal health monitoring.
Contoh arsitekturnya:
Internet
|
v
Uptime Monitor
|
| GET /up
v
Laravel
|
+---- Database check
|
+---- Redis check
|
+---- Other dependency check
Tetapi hati-hati.
Health check jangan terlalu berat.
Jangan membuat:
GET /health
kemudian menjalankan 20 query database.
Health endpoint seharusnya cepat dan benar-benar menunjukkan kesehatan dependency yang penting.
7. Monitoring HTTP Request
Setelah tahu aplikasi bisa diakses, kita perlu melihat request.
Metric dasar:
Request count
Error rate
Response time
Throughput
Status code
Contohnya:
GET /api/products
Requests/minute: 850
Average latency: 240 ms
P95: 620 ms
P99: 1.8 sec
5xx rate: 0.4%
Jangan hanya menggunakan average.
Ini kesalahan yang cukup umum.
Misalnya ada 100 request:
99 request = 100 ms
1 request = 10 sec
Average mungkin masih terlihat cukup bagus.
Tetapi satu request yang mencapai 10 detik tetap merupakan masalah.
Karena itu kita sering menggunakan:
p50;
p90;
p95;
p99.
8. Kenapa P95 dan P99 Penting?
Misalkan data response time:
p50 = 180 ms
p95 = 900 ms
p99 = 3.2 sec
Interpretasinya kurang lebih:
50% request selesai sekitar 180 ms atau lebih cepat;
95% request selesai sekitar 900 ms atau lebih cepat;
1% request berada di sekitar 3.2 detik atau lebih.
Kalau aplikasi mempunyai traffic besar, 1% bisa berarti ribuan user.
Jadi sebuah dashboard yang hanya menampilkan:
Average latency = 300ms
belum cukup.
9. Apa yang Harus Dimonitor dari HTTP?
Minimal saya akan memonitor:
Availability
Apakah endpoint bisa diakses?
Request rate
Berapa request per detik atau menit?
Error rate
Berapa HTTP:
4xx
5xx
Latency
Minimal:
p50
p95
p99
Endpoint paling lambat
Contohnya:
/api/orders
/api/reports
/api/dashboard
Endpoint paling sering dipanggil
Endpoint yang paling sering dipanggil adalah kandidat penting untuk optimasi.
10. Laravel Pulse
Untuk aplikasi Laravel, salah satu tool yang sangat menarik adalah Laravel Pulse.
Pulse dibuat untuk memberikan insight terhadap performance dan usage aplikasi Laravel.
Fitur yang tersedia mencakup antara lain:
application usage;
server stats;
queue monitoring;
slow requests;
slow jobs;
slow queries;
slow outgoing requests;
cache;
exceptions.
Artinya kita bisa mendapatkan gambaran yang jauh lebih dekat dengan aplikasi dibanding hanya melihat CPU server.
Misalnya Pulse menunjukkan:
Slow Requests
GET /reports
Average: 4.1 sec
Lalu:
Slow Queries
SELECT ...
Duration: 3.4 sec
Sekarang kita sudah mempunyai arah investigasi.
11. Pulse vs Prometheus + Grafana
Ini juga sering membingungkan.
Apakah pilih Pulse atau Prometheus + Grafana?
Sebenarnya keduanya bisa digunakan bersama.
Laravel Pulse
Fokus pada:
Laravel application
Contohnya:
slow requests
slow jobs
slow queries
exceptions
queues
cache
application usage
Prometheus
Lebih cocok sebagai sistem metrics time-series.
Prometheus mengambil metrics melalui mekanisme scraping dan menyimpannya untuk query serta alerting. Grafana memiliki datasource Prometheus secara native.
Contohnya:
CPU
RAM
Disk
Network
PHP-FPM
Nginx
Database
Redis
Application metrics
Grafana
Grafana menjadi layer visualisasi dan dashboard.
Sehingga arsitekturnya dapat seperti:
Laravel
|
+---- Pulse
|
+---- Application Metrics
|
v
Prometheus
|
v
Grafana
Jadi Pulse bukan pengganti semua observability infrastructure.
12. Laravel Logging
Logging adalah bagian penting dari monitoring.
Laravel menggunakan sistem logging berbasis channel dan Monolog, serta mendukung contextual information untuk memasukkan data tambahan seperti request ID ke log.
Contoh sederhana:
Log::info('Order created', [
'order_id' => $order->id,
'user_id' => $user->id,
]);
Log seperti ini jauh lebih berguna dibanding:
Log::info('Order created');
karena kita bisa melakukan pencarian berdasarkan order_id.
13. Jangan Membuat Log Seperti Ini
Misalnya:
Log::error('Something went wrong');
Ini hampir tidak berguna.
Kita tidak tahu:
user siapa;
request apa;
order apa;
service apa;
exception apa;
server apa.
Lebih baik:
Log::error('Failed to create payment', [
'user_id' => $user->id,
'order_id' => $order->id,
'payment_method' => $payment->method,
'exception' => $e::class,
]);
Tetap hati-hati jangan sampai memasukkan:
password
access token
credit card
API secret
session cookie
ke dalam logs.
14. Request ID
Salah satu hal sederhana yang sangat membantu adalah request_id.
Misalnya setiap request mendapatkan:
req_9fa12c3a...
Kemudian request tersebut menghasilkan log:
request_id=req_9fa12c3a
user_id=123
route=/api/orders
Lalu service lain:
request_id=req_9fa12c3a
payment service request
Sekarang kita dapat mengikuti satu request.
Laravel sendiri menyediakan Log::withContext() dan Log::shareContext() untuk membawa contextual information ke log entries.
Contoh middleware sederhana:
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class RequestId
{
public function handle(Request $request, Closure $next)
{
$requestId = (string) Str::uuid();
Log::withContext([
'request_id' => $requestId,
]);
$response = $next($request);
$response->headers->set(
'X-Request-ID',
$requestId
);
return $response;
}
}
Sekarang ketika user mengirimkan laporan:
"Order saya gagal."
Kita bisa meminta:
X-Request-ID
Kemudian melakukan pencarian log.
Ini jauh lebih efektif daripada mencari berdasarkan timestamp saja.
15. Structured Logging
Untuk aplikasi production yang cukup besar, format log sebaiknya structured.
Contohnya:
{
"level": "error",
"message": "Payment failed",
"request_id": "req-123",
"user_id": 42,
"order_id": "ORD-1001",
"service": "payment",
"exception": "PaymentTimeout"
}
Dengan format seperti ini, log dapat dengan mudah dicari dan difilter.
Misalnya:
request_id=req-123
atau:
order_id=ORD-1001
16. Pail untuk Melihat Log Laravel
Laravel juga menyediakan Pail untuk menampilkan log aplikasi dari command line. Dokumentasi logging Laravel 13 memasukkan Pail sebagai bagian dari tooling logging.
Misalnya:
php artisan pail
Untuk kasus sederhana, ini sangat membantu saat debugging.
Namun untuk production yang memiliki banyak server:
app-01
app-02
app-03
app-04
jangan bergantung hanya pada SSH satu per satu.
Kita membutuhkan centralized logging.
17. Centralized Logging
Bayangkan ada empat server:
app-01
app-02
app-03
app-04
Masing-masing menghasilkan:
storage/logs/laravel.log
Kalau terjadi error, kita harus SSH ke empat server.
Tidak ideal.
Solusinya:
app-01 ──┐
app-02 ──┤
app-03 ──┼──> Log Collector ──> Loki ──> Grafana
app-04 ──┘
Salah satu pilihan dalam ekosistem Grafana adalah:
Grafana Loki
Grafana Alloy
Grafana
Loki merupakan sistem agregasi log yang dirancang untuk mengumpulkan dan meng-query logs, serta terintegrasi dengan Grafana.
Untuk pengumpulan data, Grafana Alloy dapat menangani metrics, logs, traces, dan OpenTelemetry data.
18. Mengapa Tidak Sekadar grep laravel.log?
Untuk aplikasi kecil:
grep ERROR storage/logs/laravel.log
masih sangat masuk akal.
Tetapi pada skala besar:
10 server
100 GB logs
jutaan entries
pendekatan tersebut menjadi sulit.
Centralized log memberikan kemampuan seperti:
filter by service
filter by severity
filter by request_id
filter by user_id
filter by time range
search exceptions
dan yang paling penting:
correlate logs with metrics
19. Monitoring Exception
Error rate adalah salah satu indikator paling penting.
Misalnya:
5xx rate
naik dari:
0.1%
menjadi:
4.7%
Itu harus menarik perhatian.
Namun jangan hanya melihat jumlah.
Kita juga perlu mengelompokkan berdasarkan exception.
Contohnya:
PDOException
ConnectionException
TimeoutException
ValidationException
RedisException
Misalnya:
PDOException 4,231
PaymentTimeout 3,827
RedisException 21
Sekarang kita tahu bahwa problem besar kemungkinan ada di database atau payment service.
Laravel juga menyediakan contextual exception information sehingga context tambahan dapat disertakan pada exception logs.
20. Monitoring Database
Ini bagian yang sangat penting.
Banyak masalah Laravel production sebenarnya bukan masalah Laravel.
Masalahnya database.
Misalnya:
Laravel request = 4 sec
Developer melihat:
Controller
Service
Model
Padahal ternyata:
Database query = 3.5 sec
Maka monitoring database wajib dilakukan.
21. Apa yang Harus Dimonitor dari PostgreSQL?
Untuk PostgreSQL, beberapa hal penting adalah:
connections
active queries
waiting queries
locks
slow queries
transactions
deadlocks
cache hit ratio
I/O
disk usage
vacuum
autovacuum
replication
WAL
PostgreSQL menyediakan statistics system melalui berbagai view seperti:
pg_stat_activity
pg_stat_database
pg_stat_all_tables
pg_stat_all_indexes
pg_stat_io
pg_stat_wal
dan lainnya. Dokumentasi PostgreSQL 18 secara khusus menyediakan chapter monitoring database activity untuk hal-hal tersebut.
22. pg_stat_activity
Saat database bermasalah, salah satu query pertama yang saya cek adalah:
SELECT
pid,
usename,
state,
wait_event_type,
wait_event,
query_start,
query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY query_start;
Ini membantu melihat query yang sedang berjalan.
Misalnya:
pid state query_start query
101 active 00:00:18 SELECT ...
102 active 00:00:15 SELECT ...
103 active 00:00:12 UPDATE ...
Kalau ada query aktif selama 30 detik, kita harus investigasi.
23. PostgreSQL Connection Monitoring
Laravel 13 juga menyediakan:
php artisan db:monitor
Perintah ini dapat memonitor jumlah open connections untuk database yang dipilih dan mengirimkan DatabaseBusy event ketika jumlah koneksi melewati threshold. Dokumentasi Laravel menyarankan command tersebut dijalankan secara berkala, misalnya setiap menit.
Contoh:
php artisan db:monitor \
--databases=mysql,pgsql \
--max=100
Kemudian kita dapat membuat listener terhadap event DatabaseBusy untuk mengirim notification.
Ini cukup menarik karena monitoring database tidak harus selalu berasal dari tool eksternal.
Laravel sendiri menyediakan mekanismenya.
24. Slow Query
Satu aplikasi Laravel bisa memiliki query seperti:
SELECT *
FROM orders
WHERE user_id = 100
ORDER BY created_at DESC;
Jika tabel berisi:
100 rows
mungkin tidak masalah.
Tetapi kalau:
50 million rows
tanpa index yang tepat, query dapat menjadi bottleneck.
Untuk PostgreSQL, kita bisa menggunakan:
EXPLAIN ANALYZE
SELECT ...
Misalnya:
EXPLAIN ANALYZE
SELECT *
FROM orders
WHERE user_id = 100
ORDER BY created_at DESC;
Kemudian lihat apakah database melakukan:
Seq Scan
atau:
Index Scan
Tidak berarti semua Seq Scan otomatis buruk. Pada dataset kecil, sequential scan bisa menjadi pilihan yang benar.
Karena itu kita harus membaca execution plan, bukan sekadar mencari string Seq Scan.
25. Query Statistics
PostgreSQL juga mempunyai pg_stat_statements, yang sangat berguna untuk mencari query yang paling banyak memakan waktu atau sumber daya.
Konsepnya kira-kira:
query A
calls: 1,000,000
total execution time: 5 hours
query B
calls: 50,000
total execution time: 1 hour
Query A mungkin jauh lebih penting untuk dioptimasi karena dijalankan sangat sering.
Jadi jangan hanya bertanya:
"Query mana yang paling lambat?"
Tambahkan:
"Query mana yang paling besar dampaknya terhadap sistem?"
26. Database Connection Pool / Connection Exhaustion
Masalah production lain yang sering terjadi:
too many connections
Misalnya PostgreSQL mempunyai batas:
max_connections = 100
Kemudian aplikasi memiliki:
10 PHP-FPM workers
10 queue workers
5 scheduled workers
Ditambah monitoring tools dan service lain.
Akhirnya connection habis.
Akibatnya:
new request
↓
Laravel
↓
DB connection
↓
ERROR
Aplikasi bisa terlihat random error:
SQLSTATE:
too many connections
Inilah kenapa monitoring connection count sama pentingnya dengan CPU.
27. Redis Monitoring
Redis biasanya digunakan Laravel untuk:
cache;
session;
queue;
rate limiting;
distributed lock;
temporary data.
Redis menyediakan command INFO untuk mendapatkan statistics server, termasuk memory, clients, CPU, stats, replication, command statistics, latency statistics, dan keyspace.
Command yang paling sederhana:
redis-cli INFO
Atau:
redis-cli INFO memory
Contohnya:
used_memory
used_memory_peak
maxmemory
mem_fragmentation_ratio
28. Apa yang Harus Dimonitor di Redis?
Minimal:
memory usage
connected clients
command rate
cache hit/miss
latency
evictions
keyspace
replication
blocked clients
Kalau Redis digunakan untuk queue, tambahkan:
queue depth
processing rate
failed jobs
worker availability
29. Cache Hit Ratio
Misalnya kita memiliki:
10,000 cache requests
8,500 hits
1,500 misses
Cache hit ratio:
85%
Kalau turun menjadi:
40%
mungkin ada masalah pada:
TTL;
cache invalidation;
cache key;
deployment;
memory pressure;
strategi caching.
Jadi Redis tidak cukup dimonitor berdasarkan memory saja.
30. Laravel Queue
Queue adalah komponen yang sering terlupakan.
Misalnya user melakukan:
Upload file
Laravel kemudian:
Request
↓
Create DB record
↓
Dispatch Job
↓
Return response
Kemudian job bekerja:
Generate PDF
Send email
Process image
Call external API
Kalau worker mati, aplikasi web masih terlihat sehat.
User tetap bisa membuka:
GET /
GET /dashboard
GET /products
Semua:
HTTP 200
Tetapi email tidak terkirim.
Inilah contoh bahwa:
availability HTTP ≠ availability seluruh aplikasi.
31. Laravel Horizon
Kalau aplikasi menggunakan Redis sebagai queue backend, Laravel Horizon sangat berguna.
Horizon menyediakan dashboard untuk memonitor:
job throughput;
runtime;
failures;
queue workers;
queue metrics.
Laravel sendiri menjelaskan Horizon sebagai dashboard untuk Redis queues dan menyediakan metrics tentang throughput, runtime, serta failures.
Contohnya:
Queue: emails
Pending: 12,400
Processed/min: 800
Failed: 21
Average runtime: 2.3s
Dari sini kita bisa langsung melihat masalah.
32. Queue Backlog
Salah satu metric queue paling penting adalah:
queue depth
Misalnya:
09:00 → 10 jobs
09:05 → 200 jobs
09:10 → 1,500 jobs
09:15 → 10,000 jobs
Kalau backlog terus naik, berarti:
incoming jobs > processing capacity
Solusinya bisa:
tambah worker;
optimasi job;
pisahkan queue;
perbaiki external API;
ubah batch processing;
atau throttling.
33. Worker Saturation
Misalnya kita memiliki:
10 workers
dan semuanya sibuk.
Kemudian:
pending jobs
terus meningkat.
Masalahnya bukan hanya "queue banyak".
Kemungkinan kita kekurangan processing capacity.
Horizon dapat membantu memonitor kondisi tersebut. Untuk production, proses Horizon sendiri juga perlu diawasi oleh process monitor seperti Supervisor agar proses yang mati dapat dijalankan kembali.
34. Monitoring Failed Jobs
Laravel menyimpan failed jobs pada failed_jobs jika konfigurasi queue menggunakannya.
Kita harus memperhatikan:
failed jobs/minute
bukan hanya:
total failed jobs
Misalnya:
Total failed jobs: 100,000
belum tentu urgent.
Mungkin itu akumulasi selama dua tahun.
Tetapi:
Failed jobs:
12
15
19
44
102
dalam waktu 10 menit adalah sinyal serius.
35. Monitoring Job Duration
Misalnya job normalnya:
500 ms
Kemudian tiba-tiba:
4 sec
Lalu:
10 sec
Queue belum tentu terlihat gagal.
Tetapi throughput turun.
Akhirnya backlog meningkat.
Pulse juga menyediakan monitoring slow jobs.
36. Scheduler Laravel
Laravel Scheduler juga harus dimonitor.
Misalnya kita mempunyai:
Schedule::command('reports:generate')->daily();
Scheduler mati.
Tidak ada HTTP error.
Tidak ada user yang langsung melihat error.
Tetapi:
daily report
tidak pernah dibuat.
Inilah masalah yang sulit ditemukan jika kita hanya mengandalkan HTTP monitoring.
Laravel menyediakan Artisan commands untuk membantu menjalankan dan mengelola scheduler, dan task scheduling sebaiknya dipikirkan sebagai komponen production tersendiri.
37. Cara Memikirkan Monitoring Scheduler
Untuk setiap scheduled task, kita seharusnya mengetahui:
last successful run
last failure
duration
next run
Contohnya:
GenerateDailyReport
Last success:
2026-09-28 01:00
Duration:
18 seconds
Status:
SUCCESS
Kalau tiba-tiba:
Last success:
2026-09-27
padahal seharusnya setiap hari, kita punya indikasi bahwa scheduler bermasalah.
38. PHP-FPM
Ini salah satu bagian yang sering terlewat ketika monitoring Laravel.
Laravel berjalan melalui PHP.
Dalam deployment yang umum:
Nginx
↓
PHP-FPM
↓
Laravel
Kalau PHP-FPM kehabisan available worker, request akan menunggu.
Akibatnya:
Nginx response time ↑
padahal database mungkin baik-baik saja.
39. Metric Penting PHP-FPM
Beberapa hal yang perlu diperhatikan:
active processes
idle processes
max active processes
max children reached
request duration
slow requests
worker restarts
memory per worker
Misalnya:
pm.max_children = 20
dan monitoring menunjukkan:
active processes = 20
idle processes = 0
berarti worker sedang penuh.
Kalau kondisi ini terjadi terus-menerus, menambah database index belum tentu menyelesaikan masalah.
40. Nginx Monitoring
Nginx ada di depan aplikasi.
Karena itu kita juga perlu melihat:
requests
4xx
5xx
active connections
upstream response time
request duration
Misalnya:
Nginx latency = 3.2 sec
Laravel latency = 3.0 sec
Maka kemungkinan besar masalah memang terjadi di aplikasi atau dependency.
Tetapi jika:
Nginx latency = 3.2 sec
Laravel latency = 200 ms
kita harus melihat layer lain:
network
proxy
TLS
upstream
load balancer
41. Monitoring Server
Sekarang kita masuk ke operating system.
Minimal monitor:
CPU
RAM
Swap
Disk
Disk I/O
Network
Load Average
Processes
Open files
Tools sederhana:
top
htop
vmstat
iostat
free
df
du
ss
Misalnya:
free -h
Untuk disk:
df -h
Untuk mengetahui directory besar:
du -sh /var/*
Untuk network connection:
ss -s
Ini bukan pengganti monitoring platform, tetapi sangat berguna ketika sedang melakukan incident investigation.
42. Prometheus + Node Exporter
Kalau kita ingin monitoring server secara lebih serius, salah satu pilihan populer adalah:
Prometheus
+
Node Exporter
+
Grafana
Node Exporter mengekspos berbagai hardware dan kernel metrics pada sistem Unix-like untuk dikumpulkan oleh Prometheus. Dokumentasi Prometheus menunjukkan metrics seperti CPU, filesystem, dan network traffic melalui exporter tersebut.
Arsitekturnya:
Linux Server
|
v
Node Exporter
|
v
Prometheus
|
v
Grafana
Contohnya:
CPU = 72%
RAM = 83%
Disk = 76%
Network RX = 50 MB/s
Network TX = 30 MB/s
43. Grafana
Grafana berfungsi sebagai visualization layer.
Misalnya kita membuat dashboard:
================================================
Laravel Production
================================================
Requests/sec 850
Error Rate 0.32%
P95 Latency 420ms
CPU 61%
Memory 71%
Disk 68%
DB Connections 72/100
Redis Memory 4.2GB
Queue Pending 310
Failed Jobs 4
================================================
Dalam incident, dashboard seperti ini jauh lebih membantu daripada membuka:
top
di satu server.
44. Prometheus Itu Bukan Grafana
Ini penting.
Banyak orang baru mengira:
Prometheus = dashboard
Tidak.
Secara sederhana:
Prometheus
=
metrics collection + time-series storage + query + alerting ecosystem
Sedangkan:
Grafana
=
visualization + dashboard + exploration + alerting integrations
Grafana dapat menggunakan Prometheus sebagai datasource dan menyediakan PromQL untuk query metrics.
45. Monitoring Logs dengan Loki
Kalau Prometheus menangani metrics, Loki bisa digunakan untuk logs.
Arsitektur:
Laravel
|
| logs
v
Grafana Alloy
|
v
Loki
|
v
Grafana
Loki menyimpan log content dan mengindeks metadata/labels untuk pencarian serta integrasi dengan Grafana.
Ini memberikan pengalaman seperti:
Grafana
├── Metrics
├── Logs
└── Traces
dalam satu tempat.
46. Grafana Alloy
Dalam stack Grafana modern, Grafana Alloy dapat digunakan sebagai collector untuk telemetry.
Alloy mendukung pipeline untuk:
Prometheus metrics
OpenTelemetry
Logs
Traces
dan dapat mengirim data ke berbagai backend. Grafana sendiri mendokumentasikan Alloy sebagai collector distribution yang menggabungkan OpenTelemetry Collector components dan Prometheus exporters.
Ini menarik karena kita tidak perlu menambahkan terlalu banyak agent berbeda.
47. OpenTelemetry
Sekarang kita masuk ke observability yang lebih advance.
OpenTelemetry atau OTel digunakan untuk menghasilkan dan mengirim telemetry:
traces
metrics
logs
OpenTelemetry PHP saat ini menyediakan API/SDK untuk telemetry dan status utama metrics, traces, serta logs ditandai stable pada dokumentasi resminya.
OpenTelemetry juga menyediakan instrumentation library untuk Laravel sehingga aktivitas framework dapat menghasilkan spans.
48. Apa Itu Trace?
Bayangkan user melakukan:
POST /api/orders
Request ini melakukan:
Laravel Controller
|
+---- Validate request
|
+---- PostgreSQL INSERT
|
+---- Redis cache
|
+---- Payment API
|
+---- Queue dispatch
Dengan tracing kita bisa melihat satu trace:
POST /api/orders 2.8 sec
│
├── Laravel 2.8 sec
│
├── PostgreSQL 320 ms
│
├── Redis 15 ms
│
├── Payment API 2.1 sec
│
└── Queue dispatch 4 ms
Jelas sekali sumber latency terbesar.
Tanpa tracing, kita mungkin hanya tahu:
POST /api/orders = 2.8 sec
49. Distributed Tracing
Distributed tracing menjadi semakin penting ketika aplikasi sudah terdiri dari beberapa service.
Misalnya:
Frontend
|
v
Laravel API
|
+---- Payment Service
|
+---- Notification Service
|
+---- Search Service
Request ID membantu correlation.
Trace ID memberikan model yang lebih lengkap karena setiap operation menjadi span.
OpenTelemetry mendukung context propagation sehingga trace context dapat diteruskan antara service melalui instrumentation yang sesuai.
50. Metrics, Logs, dan Traces Harus Saling Terhubung
Ini bagian yang paling penting dari observability.
Misalnya dashboard menunjukkan:
P95 latency ↑
Metric memberi tahu:
"Ada masalah."
Kemudian kita buka trace.
Trace menunjukkan:
database query = 3 sec
Kemudian kita buka logs.
Log menunjukkan:
SQL timeout
request_id = abc123
Kemudian database monitoring menunjukkan:
connections = 99/100
Akhirnya kita menemukan:
Connection exhaustion
Alur investigasinya:
Metrics
↓
Trace
↓
Logs
↓
Database
↓
Root Cause
Inilah observability yang sebenarnya.
51. Monitoring Cache
Selain Redis server metrics, dari sisi aplikasi kita perlu mengetahui:
cache hit
cache miss
cache latency
cache invalidation
hot keys
Misalnya endpoint:
GET /products
menggunakan cache.
Ternyata cache hit rate turun:
90%
↓
40%
Maka database menerima traffic jauh lebih besar.
Akibatnya:
Redis:
healthy
Database:
overloaded
Kemungkinan penyebabnya bukan database.
Bisa saja strategi caching berubah.
52. Monitoring External API
Ini sangat penting dan sering dilupakan.
Misalnya Laravel memanggil:
Stripe
Midtrans
Google Maps
WhatsApp API
ERP Service
Internal API
Kita perlu melihat:
request count
latency
error rate
timeout
status code
Misalnya:
Payment API
Requests: 500/min
P95 latency: 2.8 sec
Timeouts: 34/min
5xx: 8%
Padahal Laravel sendiri:
CPU normal
RAM normal
Database normal
Kalau kita tidak memonitor outgoing request, kita bisa salah menyimpulkan bahwa Laravel bermasalah.
53. Studi Kasus 1: Laravel Tiba-Tiba Lambat
Sekarang kita masuk ke bagian yang lebih realistis.
Bayangkan aplikasi ecommerce.
Jam:
10:00
Customer service mulai melapor:
"Dashboard admin lambat."
Kita membuka Grafana.
Terlihat:
P95 latency
09:30 → 400ms
09:45 → 450ms
10:00 → 1.8s
10:15 → 2.4s
Jelas ada perubahan.
Step 1: Cek Server
CPU = 45%
RAM = 60%
Disk = 50%
Server tidak terlihat overload.
Step 2: Cek Laravel Pulse
Slow Requests:
GET /admin/dashboard
Duration:
2.2 sec
Step 3: Cek Slow Queries
Pulse menunjukkan:
SELECT ...
Duration:
1.9 sec
Step 4: Cek PostgreSQL
Jalankan:
SELECT
pid,
state,
wait_event_type,
wait_event,
query_start,
query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY query_start;
Kemudian ditemukan query tertentu yang lama.
Step 5: EXPLAIN ANALYZE
EXPLAIN ANALYZE
SELECT ...
Hasil menunjukkan query melakukan scan terhadap tabel besar.
Step 6: Cek Index
Ternyata developer baru menambahkan filter:
WHERE company_id = ?
AND status = ?
Tetapi index yang tersedia hanya:
company_id
Setelah mempertimbangkan query pattern, dibuat composite index yang sesuai.
Step 7: Hasil
Setelah deployment:
P95 latency
2.4 sec
↓
420 ms
Tidak perlu menambah server.
Tidak perlu menambah RAM.
Tidak perlu mengganti Laravel.
Root cause-nya:
database query
Inilah kenapa monitoring lintas layer sangat penting.
54. Studi Kasus 2: Queue Tiba-Tiba Menumpuk
Kasus kedua.
Aplikasi berjalan normal.
HTTP:
200 OK
CPU:
40%
Database:
healthy
Tetapi user mengeluh:
"Email reset password tidak masuk."
Kita membuka Horizon.
Ternyata:
Pending jobs:
18,000
Worker hanya:
5 workers
Kemudian kita lihat:
average job runtime = 8 sec
Padahal sebelumnya:
average = 700 ms
Investigasi
Kita melihat slow jobs.
Ternyata job:
SendEmailJob
melakukan request ke external email provider.
External API saat itu lambat:
2 sec
4 sec
7 sec
Karena timeout meningkat, worker menjadi sibuk.
Akhirnya:
worker capacity ↓
queue backlog ↑
Solusinya dapat berupa kombinasi:
timeout configuration
backoff
retry policy
lebih banyak workers
queue separation
external provider investigation
Horizon menyediakan konfigurasi seperti timeout, tries, backoff, worker memory, max jobs, dan max time untuk mengatur worker behavior.
55. Studi Kasus 3: Memory Server Naik Terus
Sekarang kasus berbeda.
Grafana menunjukkan:
RAM
40%
45%
51%
62%
74%
89%
96%
CPU tetap:
30%
Jadi problem bukan CPU.
Kemungkinan:
memory leak
worker terlalu besar
too many PHP-FPM workers
queue worker memory growth
database client
Redis
Kita cek PHP-FPM.
Ternyata:
20 workers
dan masing-masing mengonsumsi:
150 MB
Maka secara kasar:
20 × 150 MB
= 3 GB
Kalau server hanya memiliki:
4 GB RAM
ini sudah berbahaya.
Monitoring memory per process membantu menemukan masalah seperti ini.
56. Queue Worker dan Memory Leak
Long-running process membutuhkan perhatian ekstra.
Request Laravel biasa:
request
↓
PHP process
↓
response
↓
selesai
Queue worker berbeda.
Worker bisa hidup selama berjam-jam atau lebih lama.
Karena itu memory behavior perlu diperhatikan.
Laravel Horizon menyediakan opsi worker seperti:
memory
maxJobs
maxTime
yang dapat digunakan untuk melakukan restart worker secara berkala dan membatasi penggunaan resource. Dokumentasi Horizon juga menyebut periodic worker restart sebagai praktik yang baik untuk membantu menghadapi memory leak pada proses panjang.
57. Monitoring Disk
Ini masalah sederhana tetapi bisa sangat fatal.
Misalnya:
Disk usage = 99%
Apa yang terjadi?
Bisa:
logs gagal ditulis
database bermasalah
temporary files gagal
deployment gagal
queue gagal
Docker bermasalah
Karena itu saya biasanya membuat alert:
disk > 80%
warning.
Kemudian:
disk > 90%
critical.
Threshold tersebut bukan angka universal. Sesuaikan dengan karakteristik server dan berapa cepat disk bertambah.
58. Log Rotation
Monitoring logs juga berarti memonitor ukuran logs.
Misalnya:
laravel.log = 15 GB
Karena log tidak pernah di-rotate.
Aplikasi mungkin masih hidup, tetapi disk semakin penuh.
Karena itu production harus mempunyai:
log rotation
retention policy
centralized logging
Bukan hanya:
write log forever
59. Alerting
Dashboard saja tidak cukup.
Kalau setiap malam kita harus membuka Grafana untuk melihat apakah sistem sehat, lama-lama kita tidak melakukannya.
Monitoring harus menghasilkan alert.
Misalnya:
P95 latency > 2 sec
atau:
5xx > 2%
atau:
disk > 90%
atau:
queue backlog > 10,000
atau:
database connections > 90%
60. Jangan Terlalu Banyak Alert
Ini juga penting.
Bayangkan setiap masalah menghasilkan:
Slack
Telegram
Email
SMS
Pager
Kemudian:
CPU 70%
CPU 71%
CPU 72%
CPU 73%
CPU 74%
Mendapatkan 100 alert tidak membantu.
Yang kita butuhkan adalah actionable alert.
Contoh:
CRITICAL
Payment API timeout rate > 10%
for 5 minutes
Jauh lebih berguna.
61. Threshold Harus Berasal dari Behavior
Jangan langsung membuat:
CPU > 80% = critical
CPU 80% belum tentu masalah.
Misalnya worker CPU-intensive memang sengaja menggunakan:
85%
dan sistem tetap normal.
Sebaliknya:
CPU = 60%
dapat menjadi masalah jika:
latency ↑
queue backlog ↑
PHP-FPM saturated
Jadi threshold sebaiknya dikaitkan dengan user impact.
Contoh lebih bagus:
5xx rate > 2%
for 5 minutes
atau:
P95 latency > 2 seconds
for 10 minutes
daripada sekadar:
CPU > 80%
62. Golden Signals
Salah satu konsep terkenal dalam monitoring service adalah Four Golden Signals:
Latency
Traffic
Errors
Saturation
Untuk Laravel kita bisa menerjemahkannya menjadi:
Latency
P95
P99
Traffic
requests/sec
jobs/sec
Errors
5xx
exceptions
failed jobs
timeouts
Saturation
CPU
memory
PHP-FPM workers
DB connections
queue backlog
disk
Konsep ini sederhana tetapi sangat berguna ketika menentukan dashboard.
63. RED Method untuk API
Untuk service berbasis HTTP, konsep RED juga praktis:
Rate
Errors
Duration
Contohnya:
Rate:
1,200 req/min
Errors:
0.4%
Duration:
p95 = 600ms
Dashboard seperti ini sudah bisa memberikan gambaran kesehatan API dengan cepat.
64. USE Method untuk Infrastruktur
Untuk infrastructure kita bisa menggunakan:
Utilization
Saturation
Errors
Contoh:
CPU utilization
Disk utilization
Network utilization
Kemudian:
CPU saturation
Disk queue
PHP-FPM worker saturation
Dan:
disk errors
network errors
process errors
Ini melengkapi RED.
65. Contoh Stack Monitoring Laravel Production
Sekarang kita bisa membuat beberapa level architecture.
Level 1 — VPS Kecil
Misalnya aplikasi Laravel hanya punya:
1 VPS
2 CPU
4 GB RAM
Nginx
PHP-FPM
Laravel
PostgreSQL
Redis
Tidak perlu langsung memasang 10 tools.
Stack sederhana:
Laravel logs
Laravel health check
Laravel Pulse
Horizon
Uptime Monitor
htop
df
PostgreSQL monitoring
Redis INFO
Ini sudah cukup untuk banyak aplikasi kecil.
66. Level 2 — Production Menengah
Misalnya:
2-5 application servers
1 database server
1 Redis server
queue workers
Mulai gunakan:
Laravel Pulse
Horizon
Prometheus
Node Exporter
Grafana
Centralized logging
Arsitektur:
┌─────────────┐
│ Users │
└──────┬──────┘
│
▼
┌───────────┐
│ Nginx/LB │
└─────┬─────┘
│
┌──────────┼──────────┐
│ │ │
▼ ▼ ▼
App-01 App-02 App-03
│ │ │
└──────┬───┴──────────┘
│
┌─────────┴─────────┐
▼ ▼
PostgreSQL Redis
│ │
└─────────┬─────────┘
▼
Queue/Worker
All servers
│
├── Node Exporter
│
└── Alloy
│
├── Prometheus
└── Loki
Prometheus + Loki
│
▼
Grafana
67. Level 3 — Sistem Besar
Jika sistem sudah terdiri dari banyak service:
Laravel API
Payment Service
Notification Service
Search Service
Worker
Scheduler
Database
Redis
Message Broker
Kita bisa menggunakan:
OpenTelemetry
Prometheus
Grafana
Loki
Tempo
Alloy
Kemudian:
Metrics
↓
Prometheus/Mimir
Logs
↓
Loki
Traces
↓
Tempo
Visualization
↓
Grafana
Dengan OpenTelemetry, application traces dapat dikirim melalui OTLP ke collector/backend yang sesuai. Grafana juga menyediakan pola arsitektur menggunakan Alloy sebagai collector untuk observability production.
68. Apakah Semua Laravel Harus Menggunakan Prometheus?
Tidak.
Ini salah satu kesalahpahaman yang cukup umum.
Kalau aplikasi hanya:
1 VPS
10-100 users/day
maka:
Pulse
logs
uptime monitor
basic server monitoring
mungkin sudah cukup.
Prometheus + Grafana mulai terasa manfaatnya ketika:
server bertambah
traffic bertambah
service bertambah
metrics bertambah
incident bertambah
Tool harus mengikuti kompleksitas sistem.
Jangan membuat infrastructure monitoring lebih kompleks daripada aplikasi yang dimonitor.
69. Apakah Harus Menggunakan OpenTelemetry?
Juga tidak.
Kalau aplikasi masih monolith:
Nginx
PHP-FPM
Laravel
PostgreSQL
Redis
mungkin logs + metrics sudah cukup.
OpenTelemetry lebih terasa manfaatnya ketika kita ingin memahami:
request → service A → service B → database → external API
atau ketika tracing individual request menjadi bagian penting dari debugging.
70. Laravel Monolith Tetap Bisa Sangat Observable
Jangan berpikir:
"Observability hanya untuk microservices."
Tidak.
Monolith Laravel juga bisa mempunyai:
HTTP metrics
Laravel metrics
DB metrics
Redis metrics
queue metrics
logs
traces
server metrics
Bahkan monolith lebih mudah dimonitor karena jalur dependencynya biasanya lebih sederhana.
71. Monitoring Deployment
Production monitoring juga harus mengetahui:
"Apa yang berubah sebelum masalah terjadi?"
Misalnya:
14:00 Deployment
14:05 P95 latency naik
14:07 5xx meningkat
Korelasi seperti ini sangat berguna.
Karena itu dashboard sebaiknya memiliki deployment annotation.
Contohnya:
-----------------------------------------
P95 Latency
/
/
------ deployment ----/---------
Kalau masalah dimulai tepat setelah deploy, deployment menjadi suspect yang sangat kuat.
72. Monitoring Laravel setelah Deployment
Setelah deployment, kita bisa melakukan:
health check
smoke test
HTTP check
queue check
database check
Contohnya:
curl -f https://example.com/up
Lalu:
GET /api/health
GET /login
GET /api/products
Dan lihat:
error rate
latency
queue
database
Deployment jangan dianggap selesai hanya karena:
git pull
composer install
php artisan migrate
selesai.
Deployment selesai ketika sistem kembali sehat.
73. Apakah Telescope Cocok untuk Production?
Telescope sangat berguna untuk debugging mendalam.
Telescope dapat memberikan insight terhadap:
requests;
exceptions;
logs;
database queries;
queued jobs;
mail;
notifications;
cache;
scheduled tasks;
dan aktivitas Laravel lainnya.
Tetapi Telescope sebaiknya tidak diperlakukan sebagai pengganti monitoring platform.
Cara saya memandangnya:
Pulse
=
"bagaimana kondisi aplikasi?"
Telescope
=
"apa yang terjadi di level Laravel secara detail?"
Untuk production, akses Telescope harus diamankan dan data yang direkam harus dipertimbangkan karena bisa mengandung informasi sensitif serta menambah storage/overhead.
74. Monitoring Database Server Berbeda dengan Monitoring Query Laravel
Ini juga penting.
Laravel bisa mengatakan:
query duration = 500ms
Database server bisa menunjukkan:
CPU = 95%
I/O = 90%
connections = 99%
Keduanya adalah perspektif berbeda.
Contohnya:
Laravel
↓
query lambat
kemungkinan masalah:
database index
Tetapi:
query normal
database CPU normal
lalu latency tetap tinggi, kita bisa melihat:
network
connection establishment
application layer
Jadi jangan hanya monitor dari satu sisi.
75. Monitoring PostgreSQL yang Lebih Lengkap
Untuk production PostgreSQL, saya biasanya ingin melihat:
Connections
Active queries
Locks
Deadlocks
Transactions
Cache hit
Disk reads
Disk writes
I/O latency
Vacuum
Autovacuum
Table bloat
Index usage
WAL
Replication
Database size
PostgreSQL menyediakan banyak statistics view untuk aktivitas tersebut, termasuk pg_stat_activity, pg_stat_database, pg_stat_all_tables, pg_stat_all_indexes, dan beberapa view I/O serta WAL.
76. Monitoring Lock
Misalnya tiba-tiba banyak query menunggu.
Bisa jadi:
lock contention
Query tertentu melakukan:
UPDATE orders
...
dan transaksi terlalu lama tidak di-commit.
Query lain akhirnya menunggu.
Dari sudut pandang Laravel:
request lambat
Dari sudut pandang database:
waiting on lock
Tanpa database monitoring, root cause ini sulit ditemukan.
77. Monitoring Redis Latency
Redis sangat cepat.
Kalau Redis mulai lambat, biasanya perlu diperhatikan.
Gunakan:
redis-cli INFO stats
redis-cli INFO latency
dan lihat statistik sesuai kebutuhan.
Redis menyediakan statistik latency dalam output INFO, bersama dengan command statistics dan server/resource statistics lainnya.
78. Monitoring External Dependency
Selain database dan Redis:
SMTP
Payment Gateway
S3
Cloudflare
Third-party API
internal service
juga harus diperhatikan.
Contohnya:
Stripe API
latency p95 = 2.5 sec
Kalau Laravel request:
POST /checkout = 2.8 sec
dan tracing menunjukkan:
Stripe = 2.3 sec
kita tidak perlu menghabiskan waktu mencari masalah di Eloquent.
Root cause ada pada dependency.
79. Monitoring User Experience
Monitoring backend saja belum cukup.
Kalau aplikasi memiliki frontend yang kompleks, pertimbangkan:
frontend errors
JavaScript errors
LCP
CLS
INP
API latency
asset loading
Karena:
Laravel healthy
belum tentu:
website experience healthy
Contohnya backend:
API = 200ms
tetapi browser:
JavaScript error
dan tombol checkout tidak bekerja.
80. Apa yang Harus Ada di Dashboard Utama?
Kalau saya membuka Grafana pada jam 2 pagi karena ada alert, saya tidak ingin dashboard penuh 100 grafik.
Saya ingin melihat ringkasan:
Application Health
------------------
Availability 99.99%
Request Rate 1.2k/s
Error Rate 0.3%
P95 Latency 420ms
P99 Latency 1.8s
Infrastructure
------------------
CPU 62%
Memory 71%
Disk 68%
Database
------------------
Connections 72/100
P95 Query 180ms
Locks 3
Redis
------------------
Memory 61%
Latency 2ms
Queue
------------------
Pending 340
Failed 3
Kemudian baru ada dashboard detail.
81. Dashboard Kedua: Laravel
Dashboard khusus Laravel:
Requests
Requests/sec
Error rate
P95/P99
Slow endpoints
Exceptions
Cache hit/miss
Jobs
Slow jobs
Failed jobs
Outgoing requests
Slow queries
Pulse dapat membantu memberikan banyak insight aplikasi Laravel seperti slow requests, slow jobs, slow queries, outgoing requests, queues, exceptions, cache, dan server stats.
82. Dashboard Ketiga: Database
Contohnya:
PostgreSQL
Connections
Active queries
Waiting queries
Locks
Transactions/sec
Cache hit ratio
Disk I/O
Database size
Slow queries
Vacuum
Replication lag
WAL
83. Dashboard Keempat: Infrastructure
CPU
Memory
Swap
Disk
Disk I/O
Network
Load average
Filesystem usage
Processes
PHP-FPM
Nginx
Node Exporter dapat memberikan foundation metrics untuk monitoring resource OS melalui Prometheus.
84. Alert yang Saya Anggap Penting
Tidak ada angka universal untuk semua aplikasi, tetapi contoh rule yang masuk akal:
Availability
/health gagal beberapa kali
HTTP
5xx rate meningkat signifikan
P95 latency terus meningkat
PHP-FPM
max children reached
worker saturation
Database
connections mendekati limit
too many connections
query latency meningkat
locks meningkat
Redis
memory hampir penuh
evictions meningkat
latency meningkat
Queue
backlog terus meningkat
failed jobs meningkat
workers tidak tersedia
Server
disk hampir penuh
memory kritis
load tinggi berkepanjangan
85. Jangan Membuat Alert untuk Semua Metric
Metric:
CPU
RAM
disk
network
tidak semuanya perlu langsung membuat page.
Buat dua kategori:
warning
critical
Contoh:
Disk > 80%
=
warning
Disk > 95%
=
critical
Atau:
P95 > 1 sec
=
warning
P95 > 3 sec
=
critical
Tetapi threshold harus ditentukan berdasarkan baseline aplikasi.
86. Baseline Itu Penting
Sebelum menentukan alert:
berapa latency normal?
berapa queue normal?
berapa CPU normal?
berapa DB connections normal?
Misalnya:
Normal traffic:
500 req/s
Peak traffic:
2,000 req/s
Kalau kita membuat alert:
CPU > 70%
mungkin akan terlalu sensitif.
Lebih baik melihat:
CPU + latency + saturation
secara bersama-sama.
87. Monitoring Tidak Harus Mahal
Untuk aplikasi pribadi atau startup kecil, kita bisa mulai dari:
Laravel logs
Laravel health check
Pulse
Horizon
Uptime monitoring
htop
PostgreSQL statistics
Redis INFO
Lalu naik level:
Prometheus
Grafana
Node Exporter
Loki
Alloy
Lalu ketika membutuhkan distributed tracing:
OpenTelemetry
Ini jauh lebih realistis daripada mencoba membangun observability stack lengkap sejak hari pertama.
88. Rekomendasi Stack Berdasarkan Skala
Kondisi | Tools yang masuk akal |
|---|---|
Local development | Telescope + logs |
VPS kecil | Pulse + logs + uptime monitor |
Laravel dengan Redis Queue | Pulse + Horizon |
Beberapa server | Prometheus + Grafana + Node Exporter |
Banyak server dan centralized logs | Loki + Alloy |
Banyak service / microservices | OpenTelemetry + tracing backend |
Infrastruktur kompleks | Full observability stack |
Tidak ada kewajiban menggunakan semuanya.
89. Contoh Production Architecture yang Seimbang
Untuk banyak aplikasi Laravel production, arsitektur yang cukup masuk akal adalah:
USERS
|
v
┌──────────┐
│ CDN / LB │
└────┬─────┘
|
v
┌──────────┐
│ Nginx │
└────┬─────┘
|
v
┌──────────┐
│ PHP-FPM │
└────┬─────┘
|
v
┌──────────┐
│ Laravel │
└──┬───┬───┘
│ │
┌─────────┘ └──────────┐
v v
PostgreSQL Redis
│ │
│ v
│ Horizon
│ │
│ v
│ Workers
│
v
Monitoring
Kemudian observability:
Laravel / Server
|
+------ Metrics ------> Prometheus
|
+------ Logs ---------> Alloy -> Loki
|
+------ Traces -------> Alloy/OpenTelemetry
|
v
Tempo
|
v
Grafana
Sementara:
Laravel Pulse
Horizon
memberikan insight yang sangat spesifik terhadap ekosistem Laravel.
90. Bagaimana Saya Akan Melakukan Monitoring untuk Laravel Production?
Kalau saya harus membangun monitoring untuk aplikasi Laravel dari nol, saya tidak akan langsung menginstall semuanya.
Urutannya kira-kira seperti ini.
Tahap 1 — Health
Pastikan:
/ up
database reachable
redis reachable
Tahap 2 — Logs
Buat logging yang jelas:
request_id
user_id
exception
operation
service
dan jangan mencatat secret.
Tahap 3 — Application Monitoring
Pasang:
Laravel Pulse
untuk melihat:
slow requests
slow queries
slow jobs
exceptions
queues
cache
Tahap 4 — Queue
Kalau menggunakan Redis Queue:
Horizon
dan pastikan worker dipantau process manager.
Tahap 5 — Infrastructure
Tambahkan:
Prometheus
Node Exporter
Grafana
untuk server metrics.
Tahap 6 — Centralized Logs
Kalau server sudah bertambah:
Alloy
Loki
Grafana
Tahap 7 — Tracing
Kalau aplikasi sudah kompleks:
OpenTelemetry
untuk distributed traces.
91. Satu Hal Lagi: Monitor Monitoring System Itu Sendiri
Ini sering dilupakan.
Misalnya:
Prometheus mati
Grafana terlihat hijau karena Grafana sendiri hidup.
Tetapi metrics sebenarnya sudah tidak dikumpulkan.
Atau:
Loki penuh
sehingga logs tidak masuk.
Atau:
Alloy mati
sehingga metrics dan logs berhenti dikirim.
Jadi observability infrastructure juga harus dimonitor.
Grafana Alloy bahkan memiliki mekanisme internal telemetry/metrics yang dapat dikumpulkan untuk melakukan meta-monitoring terhadap collector itu sendiri.
92. Monitoring Harus Membantu Incident Response
Monitoring yang baik bukan hanya membuat grafik.
Ketika ada incident, operator harus bisa menjawab:
Apa yang rusak?
Sejak kapan?
Seberapa besar dampaknya?
Komponen mana yang bermasalah?
Apakah ada deployment baru?
Apakah database normal?
Apakah queue normal?
Apakah external API normal?
Apa root cause-nya?
Kalau dashboard tidak membantu menjawab pertanyaan tersebut, kemungkinan monitoring kita masih belum cukup baik.
93. Contoh Incident Flow yang Ideal
Misalnya alert masuk:
ALERT:
P95 latency > 2 sec
Langkah pertama:
1. Lihat Grafana
Ternyata:
HTTP latency ↑
DB latency ↑
Langkah kedua:
2. Lihat PostgreSQL
Ternyata:
connections = 98/100
Langkah ketiga:
3. Lihat pg_stat_activity
Ditemukan:
long running transaction
Langkah keempat:
4. Cari request terkait melalui request_id/log
Ternyata deployment baru memperkenalkan transaksi yang terlalu panjang.
Langkah kelima:
5. Rollback
Kemudian metrics:
P95:
2.8 sec
↓
500ms
Incident selesai.
Ini jauh lebih baik daripada:
SSH server
restart nginx
restart php-fpm
restart redis
restart database
tanpa tahu root cause.
94. Jangan Menjadikan Restart sebagai Solusi Utama
Ini kebiasaan yang perlu dihindari.
Contohnya:
sudo systemctl restart php8.4-fpm
Setelah restart:
CPU normal
Lalu kita menganggap:
"Solved."
Padahal mungkin:
memory leak
atau:
worker saturation
atau:
bad query
yang akan muncul lagi.
Restart boleh digunakan sebagai mitigation saat incident.
Tetapi setelah sistem kembali normal, root cause tetap harus dicari.
95. Monitoring Bukan Sekadar Mengumpulkan Data
Aplikasi yang menghasilkan:
100 metrics
1 million logs
10,000 traces
belum tentu observable.
Pertanyaan sebenarnya:
Bisakah engineer menemukan root cause dengan cepat?
Misalnya user melapor:
"Checkout lambat."
Engineer seharusnya bisa menjalankan proses seperti:
Checkout slow
↓
P95 meningkat
↓
Trace
↓
Payment API lambat
↓
Logs
↓
Timeout meningkat
↓
External provider problem
Itulah tujuan akhirnya.
96. Kesimpulan
Monitoring Laravel production sebenarnya bukan tentang mencari satu tool terbaik.
Bukan:
"Harus pakai Grafana."
Bukan juga:
"Harus pakai Prometheus."
Dan bukan:
"Laravel Pulse sudah cukup untuk semuanya."
Setiap tool menyelesaikan bagian yang berbeda.
Untuk aplikasi Laravel sederhana:
Laravel Health Check
+ Logs
+ Pulse
+ Horizon
+ Uptime Monitoring
sudah bisa memberikan fondasi yang cukup kuat.
Ketika sistem semakin besar, kita bisa menambahkan:
Prometheus
+ Node Exporter
+ Grafana
+ Loki
+ Alloy
Kemudian ketika membutuhkan distributed tracing:
OpenTelemetry
ditambahkan untuk menghubungkan request antar service.
Pada akhirnya arsitektur monitoring yang baik bukanlah arsitektur yang mempunyai paling banyak tools.
Arsitektur yang baik adalah arsitektur yang memungkinkan kita menjawab pertanyaan sederhana:
"Apa yang sedang terjadi di production, dan kenapa itu terjadi?"
Untuk Laravel, kita bisa melihatnya dari beberapa arah:
USER
|
v
HTTP / Uptime
|
v
Nginx
|
v
PHP-FPM
|
v
Laravel
/ | \
/ | \
v v v
Database Redis Queue
| | |
| | v
| | Horizon
|
v
Database
Metrics
Kemudian seluruh telemetry dikumpulkan:
Metrics ────────> Prometheus
Logs ───────────> Loki
Traces ─────────> OpenTelemetry / tracing backend
|
v
Grafana
Dan untuk Laravel sendiri:
Pulse
Horizon
Logs
Health Check
menjadi lapisan monitoring yang sangat dekat dengan aplikasi.
Jadi ketika aplikasi mengalami masalah, kita tidak lagi hanya melihat:
CPU = 70%
tetapi bisa mengatakan:
HTTP latency naik
↓
Laravel endpoint tertentu lambat
↓
query PostgreSQL meningkat
↓
connection database mendekati limit
↓
ada long-running transaction
↓
deployment terakhir memperkenalkan masalah
Itulah perbedaan antara sekadar melihat server dan benar-benar memonitor aplikasi production.
Referensi
Beberapa dokumentasi resmi yang relevan untuk memperdalam topik ini:
Laravel Deployment dan Health Check: dokumentasi Laravel 13.
Laravel Logging dan contextual logging: dokumentasi Laravel 13.
Laravel Horizon: queue monitoring, worker configuration, timeout, memory, dan deployment.
Laravel Pulse: application usage, server statistics, queues, slow requests, queries, jobs, dan exceptions.
Laravel database monitoring melalui
db:monitor.Prometheus Node Exporter untuk system metrics.
Grafana + Prometheus datasource dan alerting.
Grafana Loki untuk centralized logging.
Grafana Alloy untuk pengumpulan metrics, logs, traces, dan OpenTelemetry data.
OpenTelemetry PHP untuk metrics, logs, traces, dan instrumentation Laravel.
PostgreSQL monitoring melalui
pg_stat_activity,pg_stat_database,pg_stat_io,pg_stat_wal, dan statistics system lainnya.Redis
INFOcommand untuk server, memory, clients, statistics, latency, replication, dan command metrics.
Komentar