Prometheus ve Grafana ile İzleme
Prometheus ve Grafana ile kapsamlı izleme sistemi kurulumu. Metrik toplama, PromQL sorguları, alert yönetimi, dashboard oluşturma ve Python entegrasyonu.
Modern yazılım sistemlerinde observability (gözlemlenebilirlik), sistemlerin sağlığını ve performansını anlamak için kritik öneme sahiptir. Prometheus ve Grafana kombinasyonu, metrik toplama, depolama ve görselleştirme için en yaygın kullanılan açık kaynak çözümlerden biridir. Bu yazıda, Prometheus ve Grafana’yı kullanarak kapsamlı bir izleme sistemi kurmayı öğreneceksiniz.
Prometheus Nedir?
Prometheus, SoundCloud tarafından 2012 yılında geliştirilmiş, Cloud Native Computing Foundation (CNCF) bünyesinde yer alan açık kaynak bir izleme ve uyarı sistemidir. Zaman serisi veritabanı olarak çalışır ve pull modeli ile metrik toplar.
Prometheus’un Temel Özellikleri
- Çok boyutlu veri modeli: Metrikler, anahtar-değer çiftleri (label) ile tanımlanır
- Pull-based mimari: Prometheus, hedeflerden aktif olarak metrik çeker
- PromQL: Güçlü sorgu dili ile veri analizi
- Servis keşfi: Kubernetes, Consul, Docker gibi sistemlerle otomatik entegrasyon
- Uyarı sistemi: Alertmanager ile entegre uyarı yönetimi
Grafana Nedir?
Grafana, farklı veri kaynaklarından gelen verileri görselleştirmek için kullanılan açık kaynak bir platform olup, Prometheus ile mükemmel bir uyum sağlar. Zengin dashboard özellikleri ve esnek panel seçenekleri ile metriklerinizi anlamlı hale getirir.
Grafana’nın Temel Özellikleri
- Çoklu veri kaynağı desteği: Prometheus, InfluxDB, MySQL, PostgreSQL ve daha fazlası
- Zengin görselleştirme: Grafik, tablo, heatmap, gauge ve çok daha fazla panel tipi
- Dashboard şablonları: Hazır dashboard’lar veya özel tasarımlar
- Uyarı yönetimi: Dashboard’lardan doğrudan uyarı oluşturma
- Kullanıcı yönetimi: Ekip bazlı erişim kontrolü
Prometheus ve Grafana entegrasyon mimarisi
Prometheus Kurulumu
Docker ile Prometheus Kurulumu
Docker kullanarak Prometheus’u hızlıca çalıştırabilirsiniz:
1
2
3
4
5
6
# Prometheus yapılandırma dizini oluştur
mkdir -p /opt/prometheus/config
cd /opt/prometheus
# Temel prometheus.yml dosyası oluştur
cat > config/prometheus.yml <<EOF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
global:
scrape_interval: 15s # Her 15 saniyede metrik topla
evaluation_interval: 15s # Kuralları her 15 saniyede değerlendir
external_labels:
cluster: 'production'
region: 'eu-west-1'
# Alertmanager yapılandırması
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
# Kural dosyaları
rule_files:
- 'alerts/*.yml'
# Metrik toplama hedefleri
scrape_configs:
# Prometheus'un kendi metriklerini topla
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
labels:
env: 'production'
# Node Exporter - Sistem metrikleri
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
labels:
role: 'monitoring'
# Uygulama metrikleri
- job_name: 'my-application'
static_configs:
- targets: ['app:8080']
labels:
app: 'backend'
version: 'v1.0'
EOF
1
2
3
4
5
6
7
8
9
10
11
12
# Prometheus'u Docker ile çalıştır
docker run -d \
--name prometheus \
--restart unless-stopped \
-p 9090:9090 \
-v /opt/prometheus/config:/etc/prometheus \
-v prometheus-data:/prometheus \
prom/prometheus:latest \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/prometheus \
--storage.tsdb.retention.time=30d \
--web.enable-lifecycle
Docker Compose ile Tam Stack Kurulumu
Prometheus, Grafana ve Exporter’ları bir arada çalıştırmak için Docker Compose kullanın:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus/config:/etc/prometheus
- ./prometheus/data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
- '--web.enable-lifecycle'
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=secure_password
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-piechart-panel
- GF_SERVER_ROOT_URL=https://grafana.example.com
- GF_ANALYTICS_REPORTING_ENABLED=false
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
depends_on:
- prometheus
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
ports:
- "9100:9100"
command:
- '--path.rootfs=/host'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
volumes:
- /:/host:ro,rslave
networks:
- monitoring
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
restart: unless-stopped
ports:
- "9093:9093"
volumes:
- ./alertmanager/config:/etc/alertmanager
- alertmanager-data:/alertmanager
command:
- '--config.file=/etc/alertmanager/alertmanager.yml'
- '--storage.path=/alertmanager'
networks:
- monitoring
volumes:
prometheus-data:
grafana-data:
alertmanager-data:
networks:
monitoring:
driver: bridge
1
2
3
4
5
# Stack'i başlat
docker-compose up -d
# Logları kontrol et
docker-compose logs -f prometheus grafana
Python Uygulamasında Prometheus Entegrasyonu
Python uygulamalarınıza Prometheus metrikleri eklemek için prometheus_client kütüphanesini kullanın:
1
2
# Prometheus client kütüphanesini yükle
pip install prometheus-client
FastAPI ile Prometheus Metrikleri
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from fastapi import FastAPI, Request
from prometheus_client import Counter, Histogram, Gauge, generate_latest, CONTENT_TYPE_LATEST
from fastapi.responses import Response
import time
import psutil
app = FastAPI(title="Monitored Application")
# Metrik tanımlamaları
# Counter: Sadece artan değerler (toplam istek sayısı gibi)
http_requests_total = Counter(
'http_requests_total',
'Toplam HTTP istek sayısı',
['method', 'endpoint', 'status']
)
# Histogram: Dağılım ölçümleri (yanıt süresi gibi)
http_request_duration_seconds = Histogram(
'http_request_duration_seconds',
'HTTP istek yanıt süresi',
['method', 'endpoint'],
buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 2.5, 5.0, 10.0]
)
# Gauge: Yukarı/aşağı gidebilen değerler (CPU kullanımı gibi)
cpu_usage_percent = Gauge(
'cpu_usage_percent',
'CPU kullanım yüzdesi'
)
memory_usage_bytes = Gauge(
'memory_usage_bytes',
'Bellek kullanımı (bytes)'
)
active_users = Gauge(
'active_users',
'Aktif kullanıcı sayısı'
)
# Middleware: Her istek için metrik topla
@app.middleware("http")
async def prometheus_middleware(request: Request, call_next):
# İstek başlangıç zamanı
start_time = time.time()
# İsteği işle
response = await call_next(request)
# İstek süresi
duration = time.time() - start_time
# Metrikleri güncelle
http_requests_total.labels(
method=request.method,
endpoint=request.url.path,
status=response.status_code
).inc()
http_request_duration_seconds.labels(
method=request.method,
endpoint=request.url.path
).observe(duration)
return response
# Sistem metriklerini güncelle
@app.on_event("startup")
async def startup_event():
import asyncio
async def update_system_metrics():
while True:
# CPU kullanımını güncelle
cpu_usage_percent.set(psutil.cpu_percent(interval=1))
# Bellek kullanımını güncelle
memory = psutil.virtual_memory()
memory_usage_bytes.set(memory.used)
await asyncio.sleep(10) # Her 10 saniyede bir güncelle
asyncio.create_task(update_system_metrics())
# Metrics endpoint
@app.get("/metrics")
async def metrics():
"""Prometheus metriklerini sun"""
return Response(
content=generate_latest(),
media_type=CONTENT_TYPE_LATEST
)
# Örnek endpoint'ler
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/api/users/{user_id}")
async def get_user(user_id: int):
# Simüle edilmiş gecikme
import asyncio
await asyncio.sleep(0.1)
return {"user_id": user_id, "name": "John Doe"}
@app.post("/api/users")
async def create_user(name: str):
active_users.inc() # Aktif kullanıcı sayısını artır
return {"user_id": 123, "name": name}
@app.delete("/api/users/{user_id}")
async def delete_user(user_id: int):
active_users.dec() # Aktif kullanıcı sayısını azalt
return {"message": "User deleted"}
Özel Metrik Sınıfı
Daha organize metrik yönetimi için özel sınıf kullanın:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from prometheus_client import Counter, Histogram, Gauge, Info
from typing import Dict, Optional
import time
from functools import wraps
class ApplicationMetrics:
"""Uygulama metriklerini yöneten merkezi sınıf"""
def __init__(self, app_name: str = "application"):
self.app_name = app_name
# HTTP metrikleri
self.http_requests = Counter(
f'{app_name}_http_requests_total',
'Toplam HTTP istek sayısı',
['method', 'endpoint', 'status']
)
self.http_duration = Histogram(
f'{app_name}_http_request_duration_seconds',
'HTTP istek süresi',
['method', 'endpoint']
)
# İş mantığı metrikleri
self.business_operations = Counter(
f'{app_name}_business_operations_total',
'İş operasyonu sayısı',
['operation', 'status']
)
self.operation_duration = Histogram(
f'{app_name}_operation_duration_seconds',
'İş operasyonu süresi',
['operation']
)
# Durum metrikleri
self.active_connections = Gauge(
f'{app_name}_active_connections',
'Aktif bağlantı sayısı'
)
self.queue_size = Gauge(
f'{app_name}_queue_size',
'Kuyruk boyutu',
['queue_name']
)
# Uygulama bilgisi
self.app_info = Info(
f'{app_name}_info',
'Uygulama bilgisi'
)
def track_http_request(self, method: str, endpoint: str, status: int):
"""HTTP isteğini kaydet"""
self.http_requests.labels(
method=method,
endpoint=endpoint,
status=status
).inc()
def track_business_operation(self, operation: str, status: str = "success"):
"""İş operasyonunu kaydet"""
self.business_operations.labels(
operation=operation,
status=status
).inc()
def time_operation(self, operation_name: str):
"""Operasyon süresini ölç (decorator)"""
def decorator(func):
@wraps(func)
async def async_wrapper(*args, **kwargs):
start_time = time.time()
try:
result = await func(*args, **kwargs)
status = "success"
return result
except Exception as e:
status = "error"
raise
finally:
duration = time.time() - start_time
self.operation_duration.labels(
operation=operation_name
).observe(duration)
self.track_business_operation(operation_name, status)
@wraps(func)
def sync_wrapper(*args, **kwargs):
start_time = time.time()
try:
result = func(*args, **kwargs)
status = "success"
return result
except Exception as e:
status = "error"
raise
finally:
duration = time.time() - start_time
self.operation_duration.labels(
operation=operation_name
).observe(duration)
self.track_business_operation(operation_name, status)
# Async veya sync fonksiyon kontrolü
import asyncio
if asyncio.iscoroutinefunction(func):
return async_wrapper
return sync_wrapper
return decorator
# Singleton instance
metrics = ApplicationMetrics("myapp")
# Kullanım örneği
@metrics.time_operation("user_creation")
async def create_user(username: str, email: str) -> Dict:
"""Kullanıcı oluştur - otomatik metrik kaydı"""
# İş mantığı
import asyncio
await asyncio.sleep(0.1) # Simüle edilmiş işlem
return {
"username": username,
"email": email,
"created": True
}
PromQL Sorgu Örnekleri
PromQL (Prometheus Query Language), Prometheus’ta metrik sorgulamak için kullanılan güçlü bir dildir:
# Temel metrik sorgulama
http_requests_total
# Label filtreleme
http_requests_total{method="GET", status="200"}
# Zaman aralığında sorgu (son 5 dakika)
rate(http_requests_total[5m])
# Endpoint bazında istek oranı
sum(rate(http_requests_total[5m])) by (endpoint)
# Ortalama yanıt süresi
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
)
# CPU kullanımı %80'in üzerinde
cpu_usage_percent > 80
# Hata oranı hesaplama
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
# Bellek kullanımı artış hızı
deriv(memory_usage_bytes[10m])
# Son 1 saatteki maksimum değer
max_over_time(cpu_usage_percent[1h])
# Birden fazla label ile toplama
sum(http_requests_total) by (method, endpoint)
# Alt sorgu örneği
avg_over_time(
rate(http_requests_total[5m])[1h:1m]
)
Alertmanager Yapılandırması
Uyarıları yönetmek için Alertmanager yapılandırması:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
global:
# SMTP ayarları
smtp_smarthost: 'smtp.gmail.com:587'
smtp_from: '[email protected]'
smtp_auth_username: '[email protected]'
smtp_auth_password: 'your-app-password'
# Uyarı yönlendirme kuralları
route:
# Varsayılan alıcı
receiver: 'default-receiver'
# Grup ayarları
group_by: ['alertname', 'cluster', 'service']
group_wait: 10s
group_interval: 10s
repeat_interval: 12h
# Alt yönlendirmeler
routes:
# Kritik uyarılar
- match:
severity: critical
receiver: 'critical-receiver'
continue: true
# Database uyarıları
- match:
service: database
receiver: 'database-team'
group_wait: 5s
# Frontend uyarıları
- match:
component: frontend
receiver: 'frontend-team'
# Alıcı tanımlamaları
receivers:
- name: 'default-receiver'
email_configs:
- to: '[email protected]'
headers:
Subject: '[Prometheus] '
- name: 'critical-receiver'
# Email bildirimi
email_configs:
- to: '[email protected]'
send_resolved: true
# Slack bildirimi
slack_configs:
- api_url: 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL'
channel: '#alerts'
title: 'Kritik Uyarı: '
text: ''
# Webhook bildirimi
webhook_configs:
- url: 'http://internal-service/alerts'
send_resolved: true
- name: 'database-team'
email_configs:
- to: '[email protected]'
- name: 'frontend-team'
email_configs:
- to: '[email protected]'
# Engelleme kuralları (inhibit)
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'cluster', 'service']
Uyarı Kuralları Tanımlama
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
groups:
- name: application_alerts
interval: 30s
rules:
# Yüksek hata oranı
- alert: HighErrorRate
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/
sum(rate(http_requests_total[5m])) by (service)
) > 0.05
for: 5m
labels:
severity: critical
component: backend
annotations:
summary: "Yüksek hata oranı: "
description: " servisi % hata oranına sahip (son 5 dakika)"
# Yavaş yanıt süresi
- alert: SlowResponseTime
expr: |
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, endpoint)
) > 1
for: 10m
labels:
severity: warning
component: backend
annotations:
summary: "Yavaş yanıt süresi: "
description: " endpoint'i 95. percentile'da s yanıt süresi"
# Yüksek CPU kullanımı
- alert: HighCPUUsage
expr: cpu_usage_percent > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Yüksek CPU kullanımı"
description: "CPU kullanımı % (son 5 dakika)"
# Yüksek bellek kullanımı
- alert: HighMemoryUsage
expr: |
(memory_usage_bytes / 1024 / 1024 / 1024) > 14
for: 5m
labels:
severity: critical
annotations:
summary: "Yüksek bellek kullanımı"
description: "Bellek kullanımı GB"
# Servis durumu
- alert: ServiceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Servis çalışmıyor: "
description: " servisi 1 dakikadır erişilebilir değil"
Grafana Kurulumu ve Yapılandırması
Grafana Provisioning
Grafana’yı kod ile yapılandırmak için provisioning kullanın:
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
jsonData:
timeInterval: "15s"
queryTimeout: "60s"
httpMethod: "POST"
1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: 1
providers:
- name: 'Default'
orgId: 1
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 10
allowUiUpdates: true
options:
path: /etc/grafana/provisioning/dashboards
Python Script ile Dashboard Oluşturma
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import json
import requests
from typing import Dict, List
class GrafanaDashboard:
"""Grafana dashboard oluşturucu"""
def __init__(self, grafana_url: str, api_key: str):
self.grafana_url = grafana_url.rstrip('/')
self.api_key = api_key
self.headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
def create_dashboard(self, title: str, panels: List[Dict]) -> Dict:
"""Dashboard oluştur"""
dashboard = {
"dashboard": {
"title": title,
"tags": ["prometheus", "monitoring"],
"timezone": "browser",
"panels": panels,
"schemaVersion": 16,
"version": 0,
"refresh": "10s"
},
"overwrite": True
}
response = requests.post(
f'{self.grafana_url}/api/dashboards/db',
headers=self.headers,
json=dashboard
)
response.raise_for_status()
return response.json()
def create_graph_panel(
self,
title: str,
targets: List[Dict],
x: int = 0,
y: int = 0,
width: int = 12,
height: int = 8
) -> Dict:
"""Grafik paneli oluştur"""
return {
"title": title,
"type": "graph",
"gridPos": {"x": x, "y": y, "w": width, "h": height},
"targets": targets,
"yaxes": [
{"format": "short", "label": None},
{"format": "short", "label": None}
],
"lines": True,
"fill": 1,
"linewidth": 2,
"nullPointMode": "null",
"tooltip": {"shared": True, "sort": 0, "value_type": "individual"}
}
def create_stat_panel(
self,
title: str,
query: str,
x: int = 0,
y: int = 0,
width: int = 6,
height: int = 4
) -> Dict:
"""İstatistik paneli oluştur"""
return {
"title": title,
"type": "stat",
"gridPos": {"x": x, "y": y, "w": width, "h": height},
"targets": [{
"expr": query,
"refId": "A"
}],
"options": {
"graphMode": "area",
"colorMode": "value",
"justifyMode": "auto",
"textMode": "auto"
},
"fieldConfig": {
"defaults": {
"thresholds": {
"mode": "absolute",
"steps": [
{"value": None, "color": "green"},
{"value": 80, "color": "yellow"},
{"value": 90, "color": "red"}
]
}
}
}
}
# Kullanım örneği
if __name__ == "__main__":
grafana = GrafanaDashboard(
grafana_url="http://localhost:3000",
api_key="your-api-key-here"
)
# Panel tanımlamaları
panels = [
# İstek oranı grafiği
grafana.create_graph_panel(
title="HTTP İstek Oranı",
targets=[{
"expr": 'sum(rate(http_requests_total[5m])) by (endpoint)',
"legendFormat": "",
"refId": "A"
}],
x=0, y=0, width=12, height=8
),
# Hata oranı
grafana.create_stat_panel(
title="Hata Oranı (%)",
query='(sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))) * 100',
x=0, y=8, width=6, height=4
),
# CPU kullanımı
grafana.create_stat_panel(
title="CPU Kullanımı (%)",
query='cpu_usage_percent',
x=6, y=8, width=6, height=4
)
]
# Dashboard'u oluştur
result = grafana.create_dashboard(
title="Application Monitoring",
panels=panels
)
print("Dashboard oluşturuldu: {}".format(result))
Best Practices
1. Metrik İsimlendirme
1
2
3
4
5
6
7
8
9
# İyi örnekler
http_requests_total # Açıklayıcı, snake_case
process_cpu_seconds_total # Birim belirtilmiş
database_queries_duration_seconds # Standart birim
# Kötü örnekler
httpReq # Kısaltma, camelCase
requests # Belirsiz
response_time # Birim yok
2. Label Kullanımı
Yüksek kardinalite label’ları kullanmaktan kaçının! User ID, session ID gibi benzersiz değerleri label olarak eklemek Prometheus’un performansını ciddi şekilde düşürür.
1
2
3
4
5
6
# Doğru label kullanımı - Düşük kardinalite
http_requests_total{method="GET", endpoint="/api/users", status="200"}
# Yanlış label kullanımı - Yüksek kardinalite
# user_id gibi benzersiz değerleri label olarak kullanmayın
http_requests_total{user_id="12345"} # YANLIŞ!
3. Metrik Toplama Sıklığı
Scrape interval’ı sisteminizin ihtiyaçlarına göre ayarlayın. Çok sık toplama (5s) fazla kaynak tüketir, çok seyrek toplama (60s+) önemli olayları kaçırabilir.
1
2
3
4
5
6
7
8
9
10
# Optimal scrape interval
scrape_configs:
- job_name: 'production'
scrape_interval: 15s # Çoğu uygulama için yeterli
- job_name: 'critical-service'
scrape_interval: 5s # Kritik servisler için daha sık
- job_name: 'batch-jobs'
scrape_interval: 60s # Batch işler için daha seyrek
4. Veri Saklama
Prometheus yerel depolama için tasarlanmıştır. Uzun süreli saklama için Thanos, Cortex veya VictoriaMetrics gibi çözümler kullanın.
1
2
3
# Prometheus başlatırken retention policy belirle
--storage.tsdb.retention.time=30d # 30 gün tut
--storage.tsdb.retention.size=50GB # Maksimum 50GB
Sonuç
Prometheus ve Grafana kombinasyonu, modern yazılım sistemlerinde observability için güçlü ve esnek bir çözüm sunar. Bu yazıda öğrendiklerinizle:
- Prometheus ve Grafana’yı Docker ile deploy edebilirsiniz
- Python uygulamalarınıza metrik toplama ekleyebilirsiniz
- PromQL ile gelişmiş sorgular yazabilirsiniz
- Alertmanager ile uyarı sistemi kurabilirsiniz
- Grafana dashboard’ları oluşturabilirsiniz
Başarılı bir izleme sisteminin anahtarı, doğru metrikleri toplamak ve anlamlı görselleştirmeler oluşturmaktır. Küçük başlayıp, ihtiyaçlarınıza göre genişletin.

