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

# Gözlemlenebilirlik

> Serilog → Seq, OpenTelemetry, Prometheus /metrics, Grafana, health checks, Hangfire

Gözlemlenebilirlik üç ayağa dayanır: **structured logging** (Serilog → Seq), **metrics + tracing** (OpenTelemetry → Prometheus/Grafana) ve **health checks**. Metrics/tracing opt-in'dir.

## Logging — Serilog → Seq

API logları Serilog ile yapılandırılır (`appsettings.{Env}.json` → `Serilog`) ve Console + File + Seq sink'lerine yazılır. `UseSerilogRequestLoggingMiddleware()` her HTTP isteğini loglar; health/metrics/jobs path'leri filter ile dışlanır (gürültüyü azaltmak için).

|            | Port     | Açıklama                                                       |
| ---------- | -------- | -------------------------------------------------------------- |
| Seq ingest | `5341`   | Serilog bu adrese log gönderir (`Serilog:WriteTo[].serverUrl`) |
| Seq UI     | `5342`   | Log arama/dashboard arayüzü                                    |
| Docker iç  | `seq:80` | API container'dan ingest                                       |

Dev'de Seq auth kapalıdır (`SEQ_NO_AUTH=true`). Stage/prod'da `SEQ_ADMIN_PASSWORD` ile korunur.

## Metrics & Tracing — OpenTelemetry

OpenTelemetry, `builder.Services.AddDiyanetObservability(...)` ile kaydedilir (`BuildingBlocks.Observability`). Master flag `Observability:Enabled`'dır:

```json theme={null}
"Observability": {
  "Enabled": true,
  "Project": "a",
  "Metrics": { "Enabled": true, "EfCore": true, "Redis": true },
  "Tracing": { "Enabled": true, "SampleRatio": 1.0, "OtlpEndpoint": "http://localhost:4317" }
}
```

<Note>
  `Observability:Enabled = false` ise hiçbir OTel paketi register edilmez (sıfır maliyet). Müşteri Prometheus stack'i kullanmıyorsa bu flag false yapılır; health check ve probe'lar bağımsız çalışmaya devam eder.
</Note>

### Prometheus /metrics

`app.MapDiyanetObservabilityEndpoints()` Prometheus scrape endpoint'ini açar (default path `/metrics`). `Observability:Enabled = false` ise endpoint hiç açılmaz.

```text theme={null}
http://localhost:5005/metrics   ← API scrape endpoint
http://localhost:9090           ← Prometheus UI / PromQL
```

<Warning>
  `/metrics` dış dünyaya açık OLMAMALIDIR (cardinality + bilgi sızıntısı riski). Stage/prod'da Prometheus host port AÇMAZ — sadece Docker iç ağından scrape edilir, nginx-proxy üzerinden yönlendirilmez. İhtiyaç halinde ingress allowlist arkasına alınır.
</Warning>

### Grafana

```text theme={null}
http://localhost:3030           ← Grafana (dev, admin/admin)
https://{domain}/grafana/       ← Grafana (stage/prod subpath, basic auth)
```

Datasource (Prometheus) ve dashboard provisioning ile otomatik yüklenir; sağlanan dashboard `docker/grafana/dashboards/diyanet-health.json`'dır.

### HealthCheckMetricsPublisher

`HealthCheckMetricsPublisher` (`IHealthCheckPublisher`) her health check sonucunu bir Prometheus gauge'e yazar:

```text theme={null}
diyanet_healthcheck_status{check="postgres", tags="ready,db"}  # 2=Healthy 1=Degraded 0=Unhealthy
```

Bu sayede health durumu Grafana'da zaman serisi olarak izlenir; örn. `diyanet_healthcheck_status{check="postgres"} == 0` → kritik alarm, `avg_over_time(...[5m]) < 1.5` → flapping.

## Health check endpoint'leri

`app.MapHealthCheckEndpoints()` (`BuildingBlocks.HealthChecks`) tag-bazlı endpoint'ler açar:

| Endpoint           | İçerik                                                                                                    |
| ------------------ | --------------------------------------------------------------------------------------------------------- |
| `/health/live`     | Liveness — predicate `_ => false`, **hiçbir prob çalıştırmaz**. DB down olsa bile 200 → pod restart olmaz |
| `/health/ready`    | Readiness — `[Ready]` tag'li prob'lar (DB / cache / broker / identity)                                    |
| `/health/external` | Opsiyonel dış servisler (`[External]`) — SMTP / SMS                                                       |
| `/health/startup`  | Startup prob'ları                                                                                         |
| `/health`          | Tam detay (hata mesajları dahil)                                                                          |

Hata detayları yalnızca `/health`'te yazılır; `/health/live` ve `/health/ready` compact (status + isim + süre + tag) döner.

## Hangfire dashboard

Arka plan işler Hangfire ile yürütülür (PostgreSQL storage, `hangfire` şeması). Dashboard:

```text theme={null}
http://localhost:5005/jobs      ← Hangfire (dev: admin/admin)
```

İki server kuyruğu çalışır: `event-bus` (`event-queue`, `event-queue-dlx`) ve `command-bus` (`command-queue`, `command-queue-dlx`) — MediatR `IEventBus`/`ICommandBus` köprüsünün altyapısı.

## Sonraki adımlar

<CardGroup cols={2}>
  <Card title="Dev Docker" href="/operations/docker-dev">
    Seq/Prometheus/Grafana container'ları.
  </Card>

  <Card title="Logging building block" href="/building-blocks/logging">
    Serilog yapılandırması.
  </Card>

  <Card title="Monitoring building block" href="/building-blocks/monitoring">
    OpenTelemetry detayları.
  </Card>

  <Card title="Komutlar" href="/operations/commands">
    Log ve health kontrol komutları.
  </Card>
</CardGroup>
