> ## Documentation Index
> Fetch the complete documentation index at: https://docs.skanesgalab.my.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Manajemen Log: Grafana Loki vs ELK Stack

> Panduan sistem logging terpusat: perbandingan arsitektur Grafana Loki vs ELK (Elasticsearch, Logstash, Kibana), kapan memilihnya, dan hands-on setup Loki + Promtail + Grafana.

Jika metrik memberi tahu kita **kapan** sistem lambat dan **komponen apa** yang bermasalah, maka **Log** adalah satu-satunya instrumen yang memberi tahu kita **alasan persis (root-cause)** di balik error tersebut.

Namun, membuka SSH ke puluhan server satu per satu hanya untuk mengetikkan `tail -f /var/log/nginx/error.log` adalah cara kuno yang membuang waktu. Kita membutuhkan **Centralized Logging System (Sistem Log Terpusat)**.

***

## Perbandingan Arsitektur: Grafana Loki vs ELK Stack

Dua raksasa sistem logging di industri saat ini adalah **Grafana Loki** dan **ELK Stack (Elasticsearch, Logstash, Kibana)**:

```mermaid theme={null}
flowchart TD
    subgraph ELK["Arsitektur ELK Stack (Heavy & Full-Text Search)"]
        App1["Server / App"] --> Filebeat["Beats / Logstash"]
        Filebeat --> ES["Elasticsearch\n(Mengindeks SELURUH KATA dalam Log)\n- Butuh RAM Besar (16GB - 64GB+)\n- Biaya Storage Tinggi"]
        ES --> Kibana["Kibana UI"]
    end

    subgraph LokiArch["Arsitektur Grafana Loki (Lightweight & Label-Based)"]
        App2["Server / App"] --> Promtail["Promtail / Fluentbit"]
        Promtail --> Loki["Grafana Loki\n(HANYA Mengindeks Label Metadata)\n- Sangat Hemat RAM (512MB - 2GB)\n- Log mentah dikompres ke S3/Disk"]
        Loki --> GrafanaLoki["Grafana UI (Terpadu dengan Prometheus)"]
    end
```

| Parameter | Grafana Loki ("Prometheus untuk Log") | ELK Stack (Elasticsearch) |
| :- | :- | :- |
| **Metode Pengindeksan** | **Hanya mengindeks label metadata** (misal: `job="nginx"`, `env="prod"`). Teks log disimpan dalam blok terkompresi. | **Mengindeks seluruh isi teks** kata demi kata (*Full-Text Inverted Index*). |
| **Konsumsi RAM & CPU** | **Sangat ringan & hemat** (bisa berjalan lancar di VPS 1GB-2GB RAM). | **Sangat rakus memori** (rekomendasi minimal RAM 8GB-16GB+ untuk cluster stabil). |
| **Biaya Penyimpanan (Storage)** | Sangat murah (mendukung penyimpanan objek S3/MinIO secara langsung). | Mahal karena ukuran file index Elasticsearch bisa sama besar dengan data aslinya. |
| **Bahasa Kueri** | **LogQL** (sintaksnya mirip dengan PromQL). | Query DSL JSON Elasticsearch / KQL (Kibana Query Language). |
| **Dasbor Visualisasi** | Menyatu langsung di **Grafana** (bisa korelasi metrik + log dalam satu panel). | Menggunakan **Kibana**. |
| **Kapan Memilih?** | Cocok untuk 90% kebutuhan DevOps, Microservices, dan Kubernetes log. | Cocok jika butuh *search engine* teks rumit atau analisis data e-commerce tingkat lanjut. |

***

## Arsitektur Stack Grafana Loki

Ekosistem logging Loki terdiri dari 3 pilar:

1. **Promtail:** Agen pengumpul log ringan yang dipasang di server/kontainer untuk membaca file log lokal (seperti `/var/log/*`), menempelkan label, dan mengirimkannya ke Loki.
2. **Loki Server:** Mesin penyimpan dan pengindeks log yang sangat efisien.
3. **Grafana:** Antarmuka web untuk mencari, memfilter, dan membaca log secara interaktif menggunakan bahasa kueri **LogQL**.

***

## Hands-On: Setup Logging Terpusat (Loki + Promtail + Grafana)

Kita akan menyalakan sistem log terpusat menggunakan Docker Compose yang secara otomatis membaca dan mengumpulkan log kontainer Docker.

### 1. Buat Berkas Konfigurasi `loki-config.yaml`:

```yaml theme={null}
auth_enabled: false

server:
  http_listen_port: 3100

common:
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h
```

### 2. Buat Berkas Konfigurasi `promtail-config.yaml`:

Promtail dikonfigurasi untuk membaca file log sistem Linux dan log container:

```yaml theme={null}
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_logs
    static_configs:
      - targets:
          - localhost
        labels:
          job: varlogs
          host: web-server-01
          __path__: /var/log/*.log
```

### 3. Buat Berkas `docker-compose.yml`:

```yaml theme={null}
version: '3.8'

services:
  loki:
    image: grafana/loki:2.9.2
    container_name: loki
    restart: unless-stopped
    ports:
      - "3100:3100"
    volumes:
      - ./loki-config.yaml:/etc/loki/local-config.yaml:ro
      - loki_data:/loki
    command: -config.file=/etc/loki/local-config.yaml

  promtail:
    image: grafana/promtail:2.9.2
    container_name: promtail
    restart: unless-stopped
    volumes:
      - ./promtail-config.yaml:/etc/promtail/config.yml:ro
      - /var/log:/var/log:ro
    command: -config.file=/etc/promtail/config.yml
    depends_on:
      - loki

  grafana:
    image: grafana/grafana:10.2.2
    container_name: grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=adminrahasia
    depends_on:
      - loki

volumes:
  loki_data:
```

### 4. Menjalankan Layanan:

```bash theme={null}
docker compose up -d
```

***

## 4. Membaca & Menganalisis Log dengan LogQL di Grafana

1. Buka Grafana di `http://ip-server:3000`.
2. Tambahkan Data Source: **Connections** $\to$ **Data sources** $\to$ pilih **Loki**.
3. Isi URL Loki: `http://loki:3100` $\to$ klik **Save & test**.
4. Buka menu **Explore** (ikon kompas) di sidebar Grafana:
   * Pilih data source: **Loki**.
   * Masukkan kueri LogQL untuk mencari pesan error:

```logql theme={null}
# 1. Menampilkan seluruh log dari job 'varlogs'
{job="varlogs"}

# 2. Filter baris log yang hanya mengandung kata "error" atau "failed" (Case-Insensitive)
{job="varlogs"} |= "(?i)error"

# 3. Menghitung jumlah log error per menit (Mengubah Log menjadi Grafik Metrik!)
rate({job="varlogs"} |= "error" [1m])
```

*Dengan fitur kueri di atas, kamu dapat melihat grafik lonjakan error secara real-time dan langsung mengklik grafik tersebut untuk membaca baris pesan log penyebabnya di detik yang sama!*


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.