SLO & SLA #
Monitoring memperlihatkan bahwa service lambat. Alert memberitahu bahwa latensi naik. Tapi pertanyaan yang paling penting bagi bisnis adalah: seberapa banyak insiden yang bisa kita toleransi sebelum melanggar komitmen ke pelanggan? SLO (Service Level Objective) dan SLA (Service Level Agreement) memberikan jawaban yang terukur dan terstruktur. Ansible bisa mengotomasi seluruh infrastruktur pengukuran — dari recording rules di Prometheus hingga dashboard SLO di Grafana — sehingga kepatuhan terhadap SLO selalu terukur secara real-time.
Konsep Dasar #
SLI (Service Level Indicator)
→ Metrik aktual yang diukur
→ Contoh: persentase request dengan latensi < 200ms
SLO (Service Level Objective)
→ Target yang ingin dicapai untuk SLI
→ Contoh: 99.9% request harus selesai dalam < 200ms
Error Budget
→ Seberapa banyak SLO boleh dilanggar dalam periode tertentu
→ Error budget = 100% - SLO target
→ Contoh: dengan SLO 99.9%, error budget = 0.1% = ~43 menit/bulan
SLA (Service Level Agreement)
→ Komitmen formal ke pelanggan eksternal, dengan konsekuensi jika dilanggar
→ Biasanya lebih longgar dari SLO internal
Recording Rules untuk SLI yang Efisien #
Kalkulasi SLI yang kompleks bisa sangat mahal jika dikalkulasi setiap kali di-query. Recording rules menghitung dan menyimpan hasilnya secara berkala:
# roles/prometheus/tasks/slo-rules.yml
---
- name: Deploy recording rules untuk SLO
template:
src: rules/slo-recording.yml.j2
dest: /etc/prometheus/rules/slo-recording.yml
owner: prometheus
mode: '0644'
validate: promtool check rules %s
notify: Reload Prometheus
{# templates/rules/slo-recording.yml.j2 #}
groups:
- name: slo_recording_rules
interval: 30s
rules:
# SLI: Availability — persentase request yang berhasil (non-5xx)
- record: job:http_requests_total:success_rate5m
expr: >
sum(rate(http_requests_total{status!~"5.."}[5m])) by (job, service)
/
sum(rate(http_requests_total[5m])) by (job, service)
# SLI: Latency — persentase request dengan latensi < threshold
- record: job:http_request_duration_seconds:p99_5m
expr: >
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[5m])) by (job, service, le)
)
# Error budget burn rate (multi-window, multi-burn-rate)
# Alert jika burn rate 14x lebih cepat dari normal (akan habis dalam ~2 hari)
- record: job:error_budget_burn_rate:1h
expr: >
(1 - job:http_requests_total:success_rate5m) /
(1 - {{ slo_availability_target | default(0.999) }})
Alert Berbasis Error Budget #
Alert tradisional (CPU > 80%, latensi > 200ms) sering memunculkan false alarm. Alert berbasis error budget jauh lebih presisi — hanya alert saat error budget benar-benar terbakar dengan cepat:
{# templates/rules/slo-alerts.yml.j2 #}
groups:
- name: slo_alerts
rules:
# Alert level: page (kritis, butuh respons segera)
# Kondisi: burn rate sangat tinggi dalam window pendek
- alert: HighErrorBudgetBurnRate
expr: >
job:error_budget_burn_rate:1h > 14
and
job:error_budget_burn_rate:5m > 14
for: 2m
labels:
severity: critical
slo: availability
annotations:
summary: "Error budget terbakar cepat: {{ '{{' }} $labels.service {{ '}}' }}"
description: >
Burn rate {{ '{{' }} $value | humanize {{ '}}' }}x dari normal.
Error budget akan habis dalam {{ '{{' }} (1 / $value * 100 | humanize) {{ '}}' }} jam.
runbook_url: "https://wiki.company.com/runbooks/error-budget-burn"
# Alert level: ticket (perlu diperbaiki hari ini)
- alert: MediumErrorBudgetBurnRate
expr: >
job:error_budget_burn_rate:6h > 3
and
job:error_budget_burn_rate:30m > 3
for: 15m
labels:
severity: warning
slo: availability
annotations:
summary: "Error budget terbakar lebih cepat dari normal: {{ '{{' }} $labels.service {{ '}}' }}"
description: >
Burn rate {{ '{{' }} $value | humanize {{ '}}' }}x dari normal.
Perlu diselidiki sebelum error budget habis.
Dashboard SLO di Grafana #
- name: Deploy SLO dashboard ke Grafana
copy:
src: files/dashboards/slo-overview.json
dest: /var/lib/grafana/dashboards/slo-overview.json
owner: grafana
mode: '0640'
notify: Reload Grafana dashboards
Untuk membuat dashboard SLO yang informatif, struktur yang direkomendasikan:
Panel 1: Current Availability (gauge)
→ Menunjukkan % availability saat ini vs target SLO
Panel 2: Error Budget Remaining (gauge)
→ Sisa error budget dalam bulan berjalan (%)
Panel 3: Availability History (time series)
→ Trend availability 30 hari terakhir dengan garis SLO target
Panel 4: Latency P50/P95/P99 (time series)
→ Distribusi latensi dengan garis SLO threshold
Panel 5: Error Budget Burn Rate (time series)
→ Seberapa cepat error budget terbakar (1x = normal)
Panel 6: SLO Status per Service (table)
→ Status semua service sekaligus
Laporan SLA Otomatis #
Generate laporan kepatuhan SLA secara otomatis menggunakan Ansible dan Prometheus API:
# playbooks/generate-sla-report.yml
---
- name: Generate laporan SLA bulanan
hosts: localhost
vars:
report_month: "{{ lookup('pipe', 'date +%Y-%m') }}"
prometheus_url: "https://prometheus.company.com"
tasks:
- name: Ambil data availability bulan ini
uri:
url: "{{ prometheus_url }}/api/v1/query_range"
method: GET
body_format: form-urlencoded
body:
query: 'avg_over_time(job:http_requests_total:success_rate5m{service="myapp"}[30d])'
start: "{{ lookup('pipe', 'date -d\"first day of this month\" +%s') }}"
end: "{{ lookup('pipe', 'date +%s') }}"
step: "3600"
headers:
Authorization: "Bearer {{ vault_prometheus_token }}"
return_content: true
register: availability_data
no_log: true
- name: Kalkulasi availability rate rata-rata
set_fact:
avg_availability: >-
{{ availability_data.json.data.result[0].values
| map(attribute=1) | map('float') | sum
/ availability_data.json.data.result[0].values | length * 100 }}
- name: Generate file laporan
template:
src: sla-report.md.j2
dest: "/var/reports/sla-{{ report_month }}.md"
- name: Kirim laporan ke email tim
community.general.mail:
host: "{{ smtp_host }}"
to: "{{ sla_report_recipients }}"
subject: "Laporan SLA {{ report_month }} — {{ 'COMPLIANT' if avg_availability | float >= 99.9 else 'BREACH' }}"
body: "{{ lookup('file', '/var/reports/sla-' + report_month + '.md') }}"
Ringkasan #
- SLI → SLO → Error Budget adalah rantai yang logis: ukur SLI, tetapkan target SLO, hitung error budget yang tersisa.
- Recording rules untuk kalkulasi SLI yang kompleks — jauh lebih efisien dari query real-time di setiap evaluasi alert.
- Alert berbasis error budget burn rate mengurangi false alarm secara dramatis — hanya alert saat error budget benar-benar terancam habis.
- Multi-window burn rate (1h+5m untuk critical, 6h+30m untuk warning) menangkap masalah yang cepat maupun lambat tanpa terlalu banyak noise.
- Dashboard SLO harus menampilkan sisa error budget secara prominan — ini adalah angka yang paling bermakna untuk keputusan prioritas engineering.
- Laporan SLA otomatis via Ansible dan Prometheus API menghilangkan pekerjaan manual penyusunan laporan bulanan ke pelanggan atau manajemen.