Debugging Production Incidents — Debugging

Debugging Production Incidents Debugging di production sangat berbeda dengan development. Kamu tidak bisa sembarangan pause kode atau menambahkan console.log —

Debugging Production Incidents

Debugging di production sangat berbeda dengan development. Kamu tidak bisa sembarangan pause kode atau menambahkan console.log — aplikasi sedang digunakan user sungguhan. Butuh pendekatan sistematis dan hati-hati.

Prinsip Utama

Stabilisasi dulu, investigasi kemudian.

Saat terjadi incident, prioritas pertama adalah mengembalikan layanan — bukan menemukan root cause. Root cause bisa dicari setelah sistem stabil.

Alur Incident Response

1. Deteksi    → Alert masuk / laporan user
2. Triase     → Seberapa parah? Berapa user terdampak?
3. Koordinasi → Beri tahu tim, assign incident commander
4. Mitigasi   → Stabilisasi sistem (rollback jika perlu)
5. Investigasi → Cari root cause
6. Fix        → Perbaiki dan deploy
7. Postmortem → Dokumentasikan, cegah terulang

Deteksi Dini

// Monitor error rate dan alert jika melonjak
function analyzeErrorRate(events, windowMs = 60000) {
  const now = Date.now();
  const recent = events.filter(e => now - e.timestamp <= windowMs);

  const errors = recent.filter(e => e.type === "error").length;
  const total = recent.length;
  const errorRate = total > 0 ? errors / total : 0;

  return {
    errorRate: Math.round(errorRate * 100),  // persen
    total,
    errors,
  };
}

// Deteksi anomali — rate > 2x rata-rata
function detectAnomalies(rates) {
  const avg = rates.reduce((s, r) => s + r, 0) / rates.length;
  return rates.map((rate, i) => ({
    index: i,
    rate,
    isAnomaly: rate > avg * 2,
  }));
}

Teknik Debugging Production

1. Feature Flags

Matikan fitur bermasalah tanpa deploy:

// Semua fitur dilindungi flag
if (featureFlags.isEnabled("new-checkout")) {
  return <NewCheckout />;
}
return <OldCheckout />;

2. Canary Deployment

Deploy ke sebagian kecil user dulu:

100% traffic → old version
↓ Deploy canary
5% traffic → new version (monitor)
95% traffic → old version
↓ Jika aman, rollout bertahap
25% → 50% → 100%

3. Log Sampling

Di production, log semuanya bisa membanjiri sistem:

function shouldLog(rate = 0.1) {
  return Math.random() < rate;  // Log 10% request
}

// Log 100% error, 10% info
if (level === "error" || shouldLog(0.1)) {
  logger.log(level, message, context);
}

4. Correlation ID

Lacak satu request di seluruh sistem:

// Frontend: kirim request ID di header
const requestId = crypto.randomUUID();
fetch("/api/orders", {
  headers: { "X-Request-ID": requestId }
});

// Backend: log dengan request ID yang sama
logger.info("Order created", { requestId, orderId });

Rollback sebagai Mitigasi

Jika memungkinkan, rollback adalah mitigasi tercepat:

# Vercel
vercel rollback

# Git-based rollback
git revert HEAD --no-edit
git push origin main

# Database: jangan langsung rollback
# Jalankan migration rollback hanya jika aman
php artisan migrate:rollback

Postmortem

Setelah incident selesai, tulis postmortem:

## Incident: Checkout Down (2024-01-15 10:30 - 11:00 WIB)

**Dampak**: 150 user tidak bisa checkout selama 30 menit

**Root Cause**:
Migrasi database menambahkan kolom NOT NULL tanpa default value,
menyebabkan error saat INSERT baru.

**Timeline**:
- 10:30 - Deploy v2.3.1
- 10:32 - Alert error rate naik ke 45%
- 10:35 - Tim mendeteksi, mulai investigasi
- 10:45 - Root cause ditemukan
- 10:55 - Rollback berhasil
- 11:00 - Layanan normal

**Action Items**:
- [ ] Tambahkan default value di semua migration
- [ ] Test migration di staging sebelum production
- [ ] Perbaiki alert agar lebih cepat terdeteksi

Tips Production Debugging

  1. Jangan panik — ikuti prosedur dengan kepala dingin
  2. Komunikasikan status — update tim setiap 15-30 menit
  3. Catat semua langkah — untuk postmortem dan audit
  4. Test rollback secara berkala — pastikan bisa dilakukan saat dibutuhkan
  5. Buat runbook — dokumen langkah-langkah untuk skenario umum