Ana içeriğe geç

Cloud-Native Monitoring Stratejileri

Cloud-native monitoring, bulut ortamlarında dinamik altyapıyı izlemeyi sağlar; yanlış strateji kör noktalar yaratır ve arıza tespitini geciktirir.


1. Monolitik Monitoring Yaklaşımı Kullanmak

Yanlış Kullanım: Her servisi bağımsız izlemek.

// Her servis kendi log dosyasına yazar
builder.Host.UseSerilog((context, config) => config
    .WriteTo.File($"logs/{serviceName}.log"));
// Servisler arası ilişki görülmez, dağıtık hata takibi imkansız

İdeal Kullanım: Merkezi observability stack ile izleyin.

// Tüm servisler için ortak telemetri yapılandırması
public static class ObservabilityExtensions
{
    public static IHostApplicationBuilder AddObservability(
        this IHostApplicationBuilder builder, string serviceName)
    {
        builder.Services.AddOpenTelemetry()
            .ConfigureResource(r => r
                .AddService(serviceName)
                .AddAttributes(new Dictionary<string, object>
                {
                    ["deployment.environment"] = builder.Environment.EnvironmentName,
                    ["host.name"] = Environment.MachineName
                }))
            .WithTracing(tracing => tracing
                .AddAspNetCoreInstrumentation()
                .AddHttpClientInstrumentation()
                .AddGrpcClientInstrumentation()
                .AddOtlpExporter())
            .WithMetrics(metrics => metrics
                .AddAspNetCoreInstrumentation()
                .AddRuntimeInstrumentation()
                .AddOtlpExporter());

        builder.Logging.AddOpenTelemetry(options =>
        {
            options.IncludeScopes = true;
            options.AddOtlpExporter();
        });

        return builder;
    }
}

// Kullanım - her serviste tek satır
builder.AddObservability("order-service");

2. Container Metriklerini İzlememek

Yanlış Kullanım: Sadece uygulama metriklerini toplamak.

builder.Services.AddOpenTelemetry()
    .WithMetrics(metrics => metrics
        .AddAspNetCoreInstrumentation());
// Container CPU, memory, restart sayısı bilinmiyor

İdeal Kullanım: Container ve orchestrator metriklerini de toplayın.

# docker-compose.yml - cAdvisor ile container metrikleri
cadvisor:
  image: gcr.io/cadvisor/cadvisor:latest
  ports:
    - "8080:8080"
  volumes:
    - /:/rootfs:ro
    - /var/run:/var/run:ro
    - /sys:/sys:ro
    - /var/lib/docker/:/var/lib/docker:ro

# prometheus.yml
scrape_configs:
  - job_name: 'cadvisor'
    static_configs:
      - targets: ['cadvisor:8080']

  - job_name: 'dotnet-apps'
    dns_sd_configs:
      - names: ['tasks.order-service', 'tasks.payment-service']
        type: 'A'
        port: 8080

3. Service Mesh Observability Kullanmamak

Yanlış Kullanım: Servisler arası trafiği izlememek.

// HTTP çağrıları yapılıyor ama aralarındaki trafik izlenmiyor
await _httpClient.PostAsync("http://payment-service/api/charge", content);
// Latency nerede? Hangi servis yavaş? Bilinmiyor

İdeal Kullanım: Service mesh veya sidecar ile trafik izleyin.

# Kubernetes + Istio ile otomatik observability
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  template:
    metadata:
      annotations:
        sidecar.istio.io/inject: "true"
    spec:
      containers:
        - name: order-service
          image: order-service:latest
          env:
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              value: "http://otel-collector:4317"
            - name: OTEL_SERVICE_NAME
              value: "order-service"
// Kubernetes ortamında environment variable ile yapılandırma
builder.Services.AddOpenTelemetry()
    .ConfigureResource(r => r
        .AddService(
            serviceName: Environment.GetEnvironmentVariable("OTEL_SERVICE_NAME") ?? "unknown",
            serviceNamespace: Environment.GetEnvironmentVariable("OTEL_SERVICE_NAMESPACE") ?? "default"))
    .WithTracing(t => t.AddOtlpExporter())
    .WithMetrics(m => m.AddOtlpExporter());

4. Auto-Scaling Metrikleri Tanımlamamak

Yanlış Kullanım: Sabit instance sayısı ile çalışmak.

# Kubernetes deployment - sabit replica
spec:
  replicas: 3
  # Yoğun saatlerde yetersiz, boş saatlerde israf

İdeal Kullanım: Custom metrikler ile otomatik ölçekleme yapın.

// Queue depth metriği ile auto-scaling
public class QueueMetrics
{
    public QueueMetrics(IMeterFactory meterFactory, IQueueService queueService)
    {
        var meter = meterFactory.Create("Queue");
        meter.CreateObservableGauge("queue.pending_messages",
            () => queueService.GetPendingCount());
    }
}
# Kubernetes HPA - custom metrik ile
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: order-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order-service
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metric:
          name: http_server_requests_per_second
        target:
          type: AverageValue
          averageValue: "100"

5. Chaos Testing ile Monitoring’i Doğrulamamak

Yanlış Kullanım: Monitoring’in gerçek arızalarda çalışacağını varsaymak.

// Dashboard'lar var, alert'ler var ama hiç test edilmedi
// Gerçek arızada alert tetiklenmedi, dashboard yanlış veri gösterdi

İdeal Kullanım: Kontrollü arıza ile monitoring’i doğrulayın.

// Test endpoint'leri ile arıza simülasyonu
app.MapPost("/chaos/latency", (int delayMs) =>
{
    Thread.Sleep(delayMs);
    return Results.Ok("Latency injected");
}).RequireAuthorization("Admin");

app.MapPost("/chaos/error-rate", (double rate, IChaosFlagService flags) =>
{
    flags.SetErrorRate(rate);
    return Results.Ok($"Error rate: {rate:P0}");
}).RequireAuthorization("Admin");

// Middleware'da chaos flag kontrolü
if (_chaosFlags.ShouldInjectError())
    throw new Exception("Chaos: injected error");
// Game Day Checklist:
// 1. Bir servisi durdur → Alert tetiklendi mi?
// 2. DB bağlantısını kes → Circuit breaker açıldı mı?
// 3. Latency ekle → P95 dashboard'da görünüyor mu?
// 4. CPU stress test → Auto-scaling çalıştı mı?