# Loglarımda WARN ile ERROR seviyelerini ne zaman kullanacağıma dair net bir kural nasıl belirlerim?

> Bir satır gece 3'te birini uyandırmayı gerektiriyorsa ERROR, gerektirmiyorsa WARN yazın; hatayı sınırında bir kez loglayıp alert'i ERROR oranına bağlayın.

- Soruldu: 2026-07-21
- Yanıtlandı: 2026-07-24
- Soran: Can
- Etiketler: observability, logging
- Kaynak: https://www.muhammetsafak.com.tr/sor-bakalim/loglarimda-warn-ile-error-seviyelerini-ne-zaman-kullanacagima-dair-net-bir/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**Soru:** Laravel API'lerimiz ve Go servislerimiz neredeyse her şeyi ERROR seviyesinde logluyor — yakalanan exception'lar, başarısız validation'lar, retry'lı HTTP çağrıları, hatta beklenen 404'ler bile ERROR olarak düşüyor.

Sonuçta Sentry ve alert kanallarımız tamamen gürültüye döndü; gerçek bir sorun çıktığında binlerce anlamsız ERROR arasında kayboluyor. WARN ile ERROR arasında, ekibin tutarlı uygulayabileceği net ve uygulanabilir bir sınırı nasıl çizerim?


Kısa cevap: Seviyeyi "log satırının içeriği" değil, "birinin harekete geçmesi gerekiyor mu" sorusu belirlemeli.

## Kısa cevap

ERROR = kırdığınız bir söz; WARN = sistemin kendi kendine toparladığı beklenmedik bir durum. Yani seviyeyi satırın kaynağı değil, sonucu belirlesin. Gürültünün bir de hacim tarafı var; logların diski doldurup krize dönüştüğü senaryoyu [log storm kaydında](/sor-bakalim/log-storm-ve-disk-dolma-krizini-onlemek/) ayrıca ele almıştım.

## Neden

1. **Eksen aksiyon alınabilirliktir.** ERROR, bir isteğin veya job'ın sizin hatanızla başarısız olduğu ve birinin bakması gereken durumdur. WARN ise beklenmedik ama sistemin tolere ettiği bir şeydir: retry tuttu, fallback devreye girdi, soft limit'e yaklaşıldı. "Bu satır gece 3'te fire olsa birini uyandırır mıyım?" sorusuna evet diyorsanız ERROR'dır.
2. **Beklenen hata bug değildir.** 404, validation hatası, kullanıcının yanlış girdisi — bunlar sizin kodunuzun kırılması değil, INFO ya da en fazla WARN'dır. Kaba kural: 4xx client'ın sorunudur, 5xx sizindir. ERROR'ı yalnızca kendi kodunuzun verdiği sözü tutamadığında kullanın.
3. **Retry ve fallback farklı sonuçlar üretir.** Tekrar denenecek tek bir başarısız deneme WARN'dır; geçici bir titreme aksiyon gerektirmez. Ama tüm retry'lar tükendiğinde veya mesaj dead-letter'a düştüğünde artık ERROR'dır — çünkü iş kalıcı olarak yarım kaldı.
4. **ERROR ile FATAL/critical de aynı şey değildir.** FATAL, sürecin devam edemediği durumdur (config eksik, boot başarısız); ERROR ise bir isteğin/job'ın başarısızlığıdır, süreç ayaktadır.

## Ne yapmalı

1. **Alert'i yalnızca ERROR'a bağlayın, onu da oranla.** Uyarılarınız ERROR (ve fatal) üzerinden tetiklensin; tek satıra değil eşik/oran üzerinden ("5 dakikada 50 ERROR"). WARN dashboard'u besler, pager'ı değil.
2. **Aynı hatayı beş kez loglamayın.** Go'da her katmanda hem error return edip hem loglarsanız aynı başarısızlık beş satır olur. Kararın verildiği sınırda (handler) bir kez loglayın; alt katmanlar sadece error'ı wrap edip döndürsün. Laravel'de aynısı için `Log::error`'ı her yere serpmek yerine exception handler'daki `report()` seviyesini kullanın.

   ```go
   if err := publish(ctx, msg); err != nil {
       if attempt < maxRetries {
           log.Warn("publish failed, will retry", "attempt", attempt, "err", err)
           return retry
       }
       // retry'lar tükendi: artık gerçekten aksiyon gerekiyor
       log.Error("publish failed permanently, sent to DLQ", "err", err)
   }
   ```

3. **Her ERROR satırını aksiyon alınabilir yapın.** Her ERROR satırı, birinin gecenin bir yarısı bakacağını varsayarak yeterli context taşımalı: request/trace id, ilgili kimlikler ve wrap'lenmiş hata zinciri. Aksiyon alınamayan bir ERROR zaten ERROR değildir.

**Sonuç:** Ben olsam ekibe tek cümlelik bir kural verirdim: "Bu log gece 3'te fire olduğunda birinin uyanması gerekiyorsa ERROR, gerekmiyorsa WARN." Buna ek olarak hatayı yalnızca sınırında bir kez loglama disiplinini koyar, alert'leri ERROR oranına bağlardım. Bu iki değişiklik gürültünün çoğunu tek başına eritir; kalanını da birkaç hafta boyunca yanlış seviyedeki logları düzelterek temizlersiniz. Amaç sıfır ERROR değil; her ERROR'ın gerçekten bir anlam taşıması.

## İlgili Yazılar

- [Correlation ID'yi HTTP isteğinden kuyruğa düşen job'lara kadar nasıl taşımalıyım?](https://www.muhammetsafak.com.tr/sor-bakalim/correlation-idyi-http-isteginden-kuyruga-dusen-joblara-kadar-nasil-tasimaliyim/) — Sor Bakalım
- [Hata oranı artınca otomatik rollback yapan (self-healing) deploy altyapısını nasıl tasarlarım?](https://www.muhammetsafak.com.tr/sor-bakalim/hata-artisinda-otomatik-rollback-ve-kendi-kendini-iyilestiren-deploy/) — Sor Bakalım
- [Log storm ve disk dolma krizini nasıl önlerim?](https://www.muhammetsafak.com.tr/sor-bakalim/log-storm-ve-disk-dolma-krizini-onlemek/) — Sor Bakalım
