Centralized Logging, Loki & Alerting
Mengumpulkan log terpusat dengan Loki dan Promtail, query LogQL, merancang label, dan mengirim alert yang tidak berisik.
Log tersebar di banyak server sulit dianalisis. Centralized logging mengumpulkan log ke satu tempat; Loki menyimpan log dengan biaya relatif rendah dan terintegrasi dengan Grafana.
Mengapa log terpusat?
- Mencari error lintas server.
- Menghubungkan log dengan metrik dan trace.
- Menjaga log tetap ada saat server rusak.
- Audit dan kepatuhan.
- Mempercepat troubleshooting.
Arsitektur Loki
App / system logs
│
▼
Promtail / Grafana Alloy ──push──▶ Loki ──query──▶ GrafanaLoki mengindeks label, bukan seluruh teks. Ini membuatnya ringan, tetapi label harus dirancang dengan hati-hati.
Docker Compose
services:
loki:
image: grafana/loki:latest
restart: unless-stopped
ports:
- "127.0.0.1:3100:3100"
volumes:
- ./loki-config.yml:/etc/loki/local-config.yaml:ro
- loki-data:/loki
promtail:
image: grafana/promtail:latest
restart: unless-stopped
volumes:
- /var/log:/var/log:ro
- ./promtail-config.yml:/etc/promtail/config.yml:ro
volumes:
loki-data:Promtail
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets: [localhost]
labels:
job: varlogs
host: proxmox
__path__: /var/log/*log
- job_name: app
static_configs:
- targets: [localhost]
labels:
job: app
host: app-1
__path__: /srv/app/logs/*.logLabel yang baik
| Label | Contoh |
|---|---|
job | app, nginx, postgres |
host | app-1 |
level | error, info |
environment | production |
Jangan jadikan request ID sebagai label
Label dengan nilai unik tinggi (request ID, user ID, timestamp) membuat indeks meledak. Simpan sebagai isi log, bukan label.
LogQL
{job="app"} |= "error"
{job="app", level="error"} | json
{job="nginx"} |= " 500 "
sum(rate({job="app"} |= "error" [5m]))| Operator | Fungsi |
|---|---|
| ` | =` |
!= | Tidak mengandung |
| ` | ~` |
| ` | json` |
| ` | line_format` |
Contoh error rate log:
sum(rate({job="app"} |= "ERROR" [5m]))Alert dari log
Grafana dapat membuat alert berdasarkan query Loki.
Contoh: lebih dari 10 error per menit selama 5 menit.
sum(rate({job="app"} |= "ERROR" [1m])) > 10Atur for dan severity agar tidak berisik.
Retensi
- Tentukan berapa lama log disimpan.
- Log debug mungkin cukup 3–7 hari.
- Log audit bisa lebih lama.
- Gunakan lifecycle storage untuk kompresi/arsip.
Keamanan log
- Jangan log password, token, cookie, atau data pribadi.
- Masking data sensitif di aplikasi.
- Batasi akses Grafana/Loki.
- Enkripsi transport dan storage.
- Audit siapa yang mengakses log.
Alternatif
| Stack | Catatan |
|---|---|
| Loki + Grafana | Ringan, label-based |
| ELK/OpenSearch | Pencarian teks lengkap, resource besar |
| ClickHouse | Analitik log skala besar |
| Cloud logging | Terkelola, biaya per volume |
Praktik: log terpusat untuk aplikasi
- Pastikan aplikasi menulis log JSON ke stdout/file.
- Jalankan Loki dan Promtail.
- Kirim log app dengan label
job,host,environment. - Query error di Grafana.
- Buat alert error rate.
- Terapkan retensi.
- Uji dengan memunculkan error buatan.
Troubleshooting
| Gejala | Cek |
|---|---|
| Log tidak muncul | Path, permission, label |
| Loki penuh | Retensi, volume |
| Query lambat | Label terlalu banyak, rentang waktu |
| Alert tidak jalan | Rule, datasource, threshold |
| Log terpotong | Ukuran baris/limit |
Ringkasan
- Centralized logging memudahkan pencarian dan korelasi.
- Loki mengindeks label, bukan seluruh teks.
- Label harus stabil dan rendah kardinalitas.
- Alert log harus actionable dan tidak berisik.
Selanjutnya
Tangani insiden di Incident Troubleshooting & Production Monitoring.