Setelah aplikasimu berjalan di production, ada satu pertanyaan yang selalu muncul: bagaimana kita tahu aplikasi itu sehat? Berapa banyak request yang masuk, seberapa cepat responsnya, dan apakah ada error yang tidak terdeteksi? Di sinilah monitoring dan observability berperan. Pada tutorial ini, kamu akan belajar memantau aplikasi Python dengan Prometheus dan Grafana — dua tools open source paling populer untuk monitoring — lengkap dengan dashboard visual dan sistem alert, semuanya dijalankan dengan Docker Compose.
Apa Itu Prometheus dan Grafana?
Prometheus adalah sistem monitoring open source yang mengambil (scrape) metrik dari aplikasi lewat endpoint HTTP, lalu menyimpannya dalam time-series database. Format metriknya bisa kamu baca langsung lewat browser. Grafana, di sisi lain, adalah platform visualisasi yang membaca data dari Prometheus (dan banyak sumber lain) untuk membuat dashboard serta grafik. Keduanya saling melengkapi: Prometheus mengumpulkan dan menyimpan data, Grafana menampilkannya menjadi visual yang mudah dipahami.
Prasyarat
Untuk mengikuti tutorial ini, kamu perlu memahami dasar container. Kalau belum, baca dulu Belajar Docker untuk Pemula: Container, Dockerfile, dan Docker Compose di blog ini. Pastikan Docker dan Docker Compose sudah terpasang di komputermu.
Langkah 1 — Membuat Aplikasi Python dengan Metrik
Kita mulai dengan membuat aplikasi web Python sederhana. Saya memakai Flask di sini, tapi kamu bisa memakai FastAPI dengan pola yang hampir sama. Kalau belum paham Flask, cek dulu Membangun Aplikasi Web dengan Flask di blog ini.
Buat folder proyek baru:
mkdir monitoring-app && cd monitoring-app
Buat file requirements.txt berisi dependensi yang dibutuhkan:
flask
prometheus-client
Sekarang buat file app.py. Di sini kita membuat beberapa endpoint sederhana plus endpoint /metrics yang akan di-scrape oleh Prometheus. Kita memakai library prometheus-client untuk mendefinisikan metrik:
import time
import random
from flask import Flask, jsonify, request, g
import prometheus_client
app = Flask(__name__)
# === Definisi Metrik ===
# Counter: nilainya hanya bertambah (cocok untuk jumlah request/task)
REQUESTS = prometheus_client.Counter(
"http_requests_total",
"Total HTTP requests yang masuk",
["method", "endpoint", "status"],
)
# Histogram: mengukur distribusi durasi request dalam detik
DURATION = prometheus_client.Histogram(
"http_request_duration_seconds",
"Durasi request dalam detik",
["method", "endpoint"],
)
# Gauge: nilai yang bisa naik-turun (misal request yang sedang berjalan)
IN_PROGRESS = prometheus_client.Gauge(
"http_requests_in_progress",
"Jumlah request yang sedang diproses",
)
# Counter untuk logika bisnis
TASKS_PROCESSED = prometheus_client.Counter(
"tasks_processed_total",
"Total task yang sudah diproses",
)
@app.before_request
def mulai_timer():
g.start = time.time()
IN_PROGRESS.inc()
@app.after_request
def catat_request(response):
IN_PROGRESS.dec()
durasi = time.time() - g.start
REQUESTS.labels(request.method, request.path, response.status_code).inc()
DURATION.labels(request.method, request.path).observe(durasi)
return response
@app.route("/")
def index():
return jsonify(status="ok", message="Halo! Aplikasi contoh monitoring.")
@app.route("/slow")
def slow():
# Simulasi request yang lambat
time.sleep(random.uniform(0.1, 0.5))
return jsonify(status="ok", message="Request lambat selesai.")
@app.route("/process")
def process():
# Simulasi pemrosesan sebuah task
TASKS_PROCESSED.inc()
return jsonify(status="ok", message="Satu task diproses.")
@app.route("/metrics")
def metrics():
# Endpoint yang di-scrape Prometheus
return prometheus_client.generate_latest(), 200, {
"Content-Type": "text/plain; version=0.0.4; charset=utf-8"
}
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
Tiga jenis metrik di atas adalah dasar dari Prometheus. Counter untuk nilai yang terus naik (jumlah request, jumlah task), Gauge untuk nilai naik-turun (request yang sedang berjalan), dan Histogram untuk distribusi nilai seperti durasi. Ada juga Summary yang mirip Histogram namun dihitung di sisi aplikasi.
Tips: Coba jalankan python app.py lalu buka http://localhost:8000/metrics di browser. Kamu akan melihat semua metrik dalam format teks Prometheus. Panggil endpoint /slow dan /process beberapa kali untuk menghasilkan data.
Langkah 2 — Konfigurasi Prometheus
Selanjutnya, buat file prometheus.yml untuk memberi tahu Prometheus dari mana ia harus mengambil metrik. File ini juga mendaftarkan aturan alert yang akan kita buat nanti:
global:
scrape_interval: 15s # ambil metrik setiap 15 detik
rule_files:
- "/etc/prometheus/alert_rules.yml"
scrape_configs:
- job_name: "flask-app"
static_configs:
- targets: ["web:8000"] # nama service di docker-compose
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"] # Prometheus memantau dirinya sendiri
Langkah 3 — Menjalankan Semuanya dengan Docker Compose
Buat Dockerfile untuk aplikasi Flask:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 8000
CMD ["python", "app.py"]
Lalu buat docker-compose.yml yang menyatukan tiga service: aplikasi web, Prometheus, dan Grafana:
services:
web:
build: .
ports:
- "8000:8000"
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./alert_rules.yml:/etc/prometheus/alert_rules.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
docker compose up --build -d
Setelah semua container berjalan, kamu bisa mengakses Prometheus di http://localhost:9090 dan Grafana di http://localhost:3000 (login default: admin/admin).
Langkah 4 — Membuat Dashboard di Grafana
Buka Grafana, lalu tambahkan Prometheus sebagai data source. Masuk ke menu Configuration → Data Sources → Add data source → Prometheus, dan isi URL dengan http://prometheus:9090 (nama service di jaringan internal Docker). Klik Save & Test sampai muncul pesan sukses.
Setelah itu, buat dashboard baru (Dashboards → New → New dashboard → Add visualization) dan pilih data source Prometheus. Di kolom query, kamu memakai bahasa PromQL. Beberapa query yang berguna:
# Jumlah request per detik (rata-rata 5 menit)
rate(http_requests_total[5m])
# Request per detik, dikelompokkan per endpoint
sum by (endpoint) (rate(http_requests_total[5m]))
# Persentil ke-95 durasi request (detik)
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
# Request yang sedang berjalan saat ini
http_requests_in_progress
Tambahkan beberapa panel: satu grafik garis untuk rate request, satu panel stat untuk request yang sedang berjalan, dan satu grafik garis untuk durasi request. Dengan begitu kamu langsung punya gambaran kesehatan aplikasi secara real-time.
Peringatan: Jangan mengekspos Grafana langsung ke internet tanpa HTTPS dan autentikasi yang kuat. Untuk production, pasang reverse proxy seperti Nginx Reverse Proxy di depannya.
Langkah 5 — Mengatur Alert
Monitoring tanpa alert kurang lengkap. Kita buat aturan alert di Prometheus supaya kamu dapat notifikasi saat ada anomali. Buat file alert_rules.yml:
groups:
- name: contoh-alert
rules:
- alert: ErrorRateTinggi
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
for: 1m
labels:
severity: critical
annotations:
summary: "Terdeteksi banyak error HTTP 5xx"
description: "Rate error {{ $value }} per detik pada {{ $labels.endpoint }}"
- alert: AplikasiDown
expr: up{job="flask-app"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Aplikasi Flask tidak bisa di-scrape"
File ini sudah terdaftar lewat rule_files di prometheus.yml dan di-mount di docker-compose. Setelah dijalankan, kamu bisa melihat alert yang aktif di http://localhost:9090/alerts. Alternatif yang lebih ramah pemula adalah mengatur alert langsung di Grafana (menu Alerting → Alert rules → New alert rule), yang juga bisa mengirim notifikasi ke email, Slack, atau Telegram.
Metrik Kustom untuk Logika Bisnis
Selain metrik HTTP bawaan, kamu bisa menambahkan metrik yang relevan dengan bisnismu, seperti jumlah user yang mendaftar, total penjualan, atau lama proses background job. Pada kode di atas, TASKS_PROCESSED adalah contoh metrik bisnis: setiap endpoint /process dipanggil, counter-nya bertambah satu. Kamu bisa membuat grafik pertumbuhan task dengan query rate(tasks_processed_total[5m]).
Kesimpulan
Kamu sekarang punya sistem monitoring lengkap: aplikasi Python yang mengekspos metrik, Prometheus yang mengumpulkannya, Grafana yang menampilkannya sebagai dashboard, dan alert yang memberi tahu saat ada masalah. Ini adalah fondasi observability yang bisa langsung kamu terapkan ke aplikasi nyata. Selamat mencoba!
FAQ (Pertanyaan Umum)
Apa perbedaan Prometheus dan Grafana?
Prometheus bertugas mengumpulkan (scrape) dan menyimpan metrik dalam time-series database, sedangkan Grafana bertugas memvisualisasikan data tersebut menjadi grafik dan dashboard. Keduanya sering dipakai bersama karena saling melengkapi.
Apakah Prometheus bisa menyimpan data dalam jangka panjang?
Secara default Prometheus menyimpan data di disk lokal dengan retensi sekitar 15 hari. Untuk penyimpanan jangka panjang, kamu bisa memakai remote write ke storage seperti Thanos, Cortex, atau VictoriaMetrics.
Apakah Grafana hanya bisa memakai Prometheus?
Tidak. Grafana mendukung banyak data source seperti PostgreSQL, MySQL, InfluxDB, Elasticsearch, Loki (untuk log), dan masih banyak lagi. Kamu bisa menggabungkan beberapa sumber dalam satu dashboard.