Bu blog yazısında, bir e-ticaret uygulamasını izlemek için Prometheus, Jaeger, OpenTelemetry ve Grafana’yı nasıl entegre edeceğimizi adım adım inceleyeceğiz. Örneğimizde, bir sipariş oluşturma senaryosunu izleyeceğiz ve servis metriklerini Prometheus’ta görselleştireceğiz.
Servisleri Başlatma Öncelikle, order-service ve payment-service servislerini çalışır hale getirelim. Bu servisler hem izleme hem de metrik verisi üretecek.
Dizin Yapısını Oluşturun:
project/
├── order-service/
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── payment-service/
│ ├── app.py
│ ├── Dockerfile
│ └── requirements.txt
├── collector-config.yaml
├── prometheus.yml
└── docker-compose.yml
Kod Dosyalarını Oluşturun:
order-service/app.py:
python
from opentelemetry import trace, metrics
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from flask import Flask, request
import requests
import logging
# Log ekleme
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Tracer'ı yapılandır
trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)
otlp_trace_exporter = OTLPSpanExporter(endpoint="otel-collector:4317", insecure=True)
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(otlp_trace_exporter))
# Metrikleri yapılandır
metrics.set_meter_provider(MeterProvider(metric_readers=[PeriodicExportingMetricReader(OTLPMetricExporter(endpoint="otel-collector:4317", insecure=True))]))
meter = metrics.get_meter(__name__)
order_counter = meter.create_counter("order_requests_total", description="Toplam sipariş isteği sayısı")
app = Flask(__name__)
@app.route('/order', methods=['POST'])
def create_order():
with tracer.start_as_current_span("create-order"):
logger.info("Order servisi izleme başlatıldı")
order_counter.add(1) # Metrik artırımı
payment_response = requests.post("http://payment-service:5001/pay")
if payment_response.status_code != 200:
logger.error(f"Payment servisine istek başarısız: {payment_response.status_code}")
return "Sipariş oluşturuldu", 200
if __name__ == "__main__":
logger.info("Order servisi başlatılıyor...")
app.run(host="0.0.0.0", port=5000)
payment-service/app.py:
python
from opentelemetry import trace, metrics
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from flask import Flask, request
import time
import logging
# Log ekleme
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Tracer'ı yapılandır
trace.set_tracer_provider(TracerProvider())
tracer = trace.get_tracer(__name__)
otlp_trace_exporter = OTLPSpanExporter(endpoint="otel-collector:4317", insecure=True)
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(otlp_trace_exporter))
# Metrikleri yapılandır
metrics.set_meter_provider(MeterProvider(metric_readers=[PeriodicExportingMetricReader(OTLPMetricExporter(endpoint="otel-collector:4317", insecure=True))]))
meter = metrics.get_meter(__name__)
payment_counter = meter.create_counter("payment_requests_total", description="Toplam ödeme isteği sayısı")
app = Flask(__name__)
@app.route('/pay', methods=['POST'])
def process_payment():
with tracer.start_as_current_span("process-payment"):
logger.info("Payment servisi izleme başlatıldı")
payment_counter.add(1) # Metrik artırımı
time.sleep(0.5) # Ödeme işlemini simüle etmek için gecikme
return "Ödeme tamamlandı", 200
if __name__ == "__main__":
logger.info("Payment servisi başlatılıyor...")
app.run(host="0.0.0.0", port=5001)
Dockerfile’ları Oluşturun:
order-service/Dockerfile:
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
payment-service/Dockerfile:
dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
Bağımlılık Dosyalarını Oluşturun:
order-service/requirements.txt ve payment-service/requirements.txt:
flask==2.3.3
requests==2.31.0
opentelemetry-api==1.20.0
opentelemetry-sdk==1.20.0
opentelemetry-exporter-otlp-proto-grpc==1.20.0
Docker Compose Dosyasını Oluşturun:
docker-compose.yml:
version: '3'
services:
order-service:
build: ./order-service
ports:
- "5000:5000"
depends_on:
- otel-collector
payment-service:
build: ./payment-service
ports:
- "5001:5001"
depends_on:
- otel-collector
otel-collector:
image: otel/opentelemetry-collector
volumes:
- ./collector-config.yaml:/etc/otelcol/config.yaml
ports:
- "4317:4317"
- "9091:9091"
depends_on:
- jaeger
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
jaeger:
image: jaegertracing/all-in-one
ports:
- "16686:16686"
- "14250:14250"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
Yapılandırma Dosyalarını Oluşturun:
collector-config.yaml:
receivers:
otlp:
protocols:
grpc:
endpoint: "0.0.0.0:4317"
exporters:
prometheus:
endpoint: "0.0.0.0:9091"
otlp/jaeger:
endpoint: "jaeger:14250"
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlp/jaeger]
metrics:
receivers: [otlp]
exporters: [prometheus]
prometheus.yml:
yaml
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 5s
static_configs:
- targets: ['otel-collector:9091']
Servisleri Başlatın:
Proje kök dizininde terminal açın ve şu komutu çalıştırın:
docker-compose up --build
Servislerin Çalıştığını Doğrulayın: Endpoint’leri Test Edin: curl -X POST http://localhost:5000/order Jaeger UI: http://localhost:16686 Prometheus UI: http://localhost:9090 Grafana UI: http://localhost:3000 (varsayılan kullanıcı: admin, şifre: admin) Senaryo Uygulama: Python tabanlı bir e-ticaret API’si. Servisler: order-service: Sipariş oluşturur ve ödeme servisine istek gönderir. payment-service: Ödeme işlemini simüle eder. Amaç: Metrikler (örneğin, istek sayıları) Prometheus ile toplanacak. İsteklerin servisler arası akışı Jaeger ile izlenecek. OpenTelemetry telemetri verilerini sağlayacak. Grafana tüm verileri görselleştirecek.
- OpenTelemetry ile Veri Toplama Servislerimizde OpenTelemetry hem izleme (traces) hem de metrik verisi üretiyor:
order_requests_total: Toplam sipariş isteği sayısı. payment_requests_total: Toplam ödeme isteği sayısı. 2. OpenTelemetry Collector ile Verileri Yönlendirme Collector, OTLP protokolüyle verileri alır, izlemeleri Jaeger’a (otlp/jaeger), metrikleri Prometheus’a gönderir.
- Prometheus ile Metrik Depolama Prometheus, Collector’dan metrikleri çeker.
Örnek Sorgular (PromQL): Toplam sipariş isteği sayısı: order_requests_total Toplam ödeme isteği sayısı: payment_requests_total İstek oranı: rate(order_requests_total[5m]) 4. Jaeger ile Dağıtık İzleme Jaeger, izleme verilerini görselleştirir.
Açıklama: http://localhost:16686 adresinde create-order ve process-payment izlemeleri görünmeli. 5. Grafana ile Görselleştirme Grafana, Prometheus ve Jaeger verilerini birleştirir.
Veri Kaynakları: Prometheus: http://prometheus:9090 Jaeger: http://jaeger:16686 Örnek Panel: Sipariş isteği oranı: rate(order_requests_total[5m]) Test ve Sonuç Test Komutu: curl -X POST http://localhost:5000/order Sonuçlar: Jaeger’da: create-order ve process-payment izlemeleri. Prometheus’ta: order_requests_total ve payment_requests_total metrikleri. Grafana’da: Metrikler ve izlemeler. Hata Giderme 405 Hatası: curl -X POST kullandığınızdan emin olun. Metrikler Görünmüyorsa: docker-compose logs order-service ve payment-service ile metriklerin üretildiğini kontrol edin. Prometheus UI’da order_requests_total ve payment_requests_total metriklerini arayın. Uygulama Bu yapı, performans darboğazlarını tespit eder ve sistem sağlığını izler.