Alerting & On-Call — DevOps

Alerting: Reaksi Otomatis terhadap Masalah Monitoring tanpa alerting hanya dashboard yang tidak pernah dilihat. Alerting memberi notifikasi saat metric…

Alerting adalah aturan yang memantau metric dan memanggil orang saat ada masalah yang butuh tindakan. On-call adalah giliran jaga: siapa yang dipanggil, kapan, dan apa yang dia lakukan. Bayangin alarm asap di dapur. Alarm yang baik gak menjerit tiap kali roti sedikit gosong, tapi pasti menjerit kalau asapnya bertahan. Dan kalau kebakaran sungguhan, pemadam kebakaran punya jadwal piket dan kartu SOP di dinding. Monitoring tanpa alert cuma dashboard yang gak pernah dilihat jam 3 pagi.

Di pelajaran Metrics & Monitoring, Prometheus sudah menyimpan error rate catatan-api tiap 15 detik. Sekarang kita pasang aturan di atasnya.

🧪 Tebakan cepat: waktu deploy, container catatan-api restart dan error rate melonjak ke 7,8% selama 2 menit, lalu normal lagi. Aturannya: error rate di atas 5% dengan for: 5m. On-call ditelepon atau gak? Jawabannya ada di bagian "Ambang dan for:".

Anatomi alert rule

Aturan Prometheus ditulis di file YAML, dan Prometheus mengevaluasinya tiap menit:

groups:
  - name: catatan-api
    rules:
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{job="catatan-api",status_code=~"5.."}[1m]))
            / sum(rate(http_requests_total{job="catatan-api"}[1m])) * 100 > 5
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Error rate catatan-api di atas 5%"
          runbook_url: "https://wiki.example.com/runbooks/catatan-api-error-rate"

Prometheus cuma memutuskan "firing" atau gak. Yang mengirim notifikasi adalah Alertmanager: mengelompokkan alert, membuang duplikat, dan meneruskannya ke telepon on-call atau Slack.

Satu aturan, satu nilai

Inti dari tiap evaluasi: bandingkan nilai sekarang dengan ambang memakai operator aturannya.

function evaluateAlert(rule, currentValue) {
  let triggered = false;
  if (rule.operator === ">") triggered = currentValue > rule.threshold;
  if (rule.operator === "<") triggered = currentValue < rule.threshold;
  if (rule.operator === ">=") triggered = currentValue >= rule.threshold;
  if (rule.operator === "<=") triggered = currentValue <= rule.threshold;
  return { triggered, severity: rule.severity, metric: rule.metric, currentValue, threshold: rule.threshold };
}
Aturan Nilai sekarang triggered
error_rate > 0.05, critical 0.08 true (8% di atas 5%)
cpu >= 90, warning 85 false
disk < 10 (sisa disk %), critical 5 true

Ambang dan for:

Prometheus mengevaluasi aturan tiap menit, dan alert punya tiga keadaan:

Kalau kondisinya salah saat masih pending, alert dibuang tanpa notifikasi. Ini dua seri dari Lab dengan ambang 5% dan for: 5m:

Seri Di atas 5% pending firing Notifikasi
blip deploy 10:08 sampai 10:09 10:08 sampai 10:09 gak pernah 0
insiden 10:14 sampai 10:23 10:14 sampai 10:18 10:19 sampai 10:23 10:19 firing, 10:24 resolved

Blip 2 menit gak pernah sampai 5 menit, jadi gak ada yang ditelepon. Itu jawaban tebakannya. Tapi harganya terlihat di baris kedua: insiden sungguhan baru memanggil orang 5 menit setelah dimulai. for: membeli ketenangan dengan keterlambatan; untuk masalah yang dirasakan semua user, 2 sampai 5 menit sudah cukup.

Flapping

Seri ketiga di Lab naik turun di sekitar 5%: 5,4, lalu 4,7, lalu 5,3, lalu 4,6. Dengan for: 0m, alert firing, resolved, firing lagi, 12 kali dalam 30 menit. Ini disebut flapping: satu masalah, belasan telepon. Cara meredamnya:

Di Lab, for: 2m ditambah keep_firing_for: 5m menghasilkan satu notifikasi pukul 10:13, dan alert tetap firing selama masalahnya ada.

Gejala, bukan penyebab

Telepon orang untuk gejala yang dirasakan user: error rate tinggi, p99 lambat, situs gak bisa dibuka. Jangan untuk penyebab yang mungkin: CPU 90% saat semua request tetap cepat dan berhasil gak merugikan siapa pun. Penyebab tempatnya di dashboard dan tiket, dan dipakai saat menyelidiki gejala.

Setiap alert harus actionable: ada yang harus dilakukan begitu bunyi. Alert yang bunyi terus tapi gak pernah butuh tindakan melahirkan alert fatigue: orang kebal, lalu alert yang penting ikut diabaikan. Obatnya: cuma alert yang actionable, ambang dan for: yang tepat, dan severity yang jelas.

Severity: page atau tiket

Severity Contoh di catatan-api Ke mana
critical error rate di atas 5% selama 5 menit, situs down page: telepon on-call, jam berapa pun
warning sertifikat TLS habis dalam 14 hari, disk 80% tiket di Slack #catatan-alerts, dikerjakan jam kerja

Alertmanager membaca label severity dan meneruskan alert:

route:
  receiver: slack-tiket            # default: tiket di Slack
  routes:
    - matchers: ['severity="critical"']
      receiver: pagerduty-oncall   # critical: telepon on-call

Banyak tim juga memakai tingkat insiden SEV1 sampai SEV4: SEV1 layanan mati untuk semua user, SEV4 masalah kosmetik.

Runbook dan on-call

Runbook adalah halaman yang ditautkan dari alert: apa artinya, dashboard mana yang dibuka, langkah pertama (misalnya "cek deploy terakhir, rollback kalau error mulai setelahnya"), dan siapa yang dihubungi. Orang yang dibangunkan jam 3 pagi gak perlu berpikir dari nol.

On-call rotation membagi giliran: misalnya tiap minggu satu orang jadi primary dan satu secondary, bergiliran. Layanan seperti PagerDuty, Opsgenie, atau Grafana OnCall memegang jadwalnya dan escalation policy: kalau primary gak acknowledge dalam 5 menit, alert naik ke secondary. Urutan saat dipanggil: acknowledge (aku pegang), nilai dampaknya, mitigasi dulu (rollback, matikan feature flag), baru cari akar masalahnya. Penulisan postmortem setelahnya dibahas di pelajaran Incident Response & Postmortems.

⚠️ Jebakan yang sering ketemu

TL;DR: Alert rule membandingkan metric dengan ambang (operator >, <, >=, <=) setiap evaluasi, dan for: menahannya di pending sampai kondisinya bertahan, jadi blip 2 menit gak membangunkan orang, dengan harga insiden sungguhan baru dipanggil setelah for: habis. Seri yang naik turun di sekitar ambang membuat flapping; redam dengan for:, keep_firing_for, atau ambang yang jujur. Page untuk gejala yang dirasakan user (error rate, p99), tiket untuk penyebab dan hal yang bisa menunggu, dan hapus alert yang gak actionable, supaya gak terjadi alert fatigue. Severity critical jadi telepon on-call, warning jadi tiket, diatur Alertmanager. Tiap alert menautkan runbook, dan rotasi on-call punya primary, secondary, dan eskalasi kalau gak ada yang acknowledge.

Yang akan kamu pelajari