İçeriğe Atla
Mustafa Erbay
Yaşam · 10 dk okuma · görüntülenme Read in English

Log Seviye Stratejisi: Geliştirici Rahatlığı mı, Operasyonel Yük mü?

Yazılım geliştirirken gelişi güzel eklenen logların üretim ortamında yarattığı operasyonel yükü, performans kayıplarını ve doğru log seviye stratejisini…

100%

Yazılımcı olarak hepimiz yazdığımız kodun üretim ortamında (production) nasıl davrandığını anlamak isteriz. Bu isteğin en doğal sonucu da kodun her köşesine, her karar mekanizmasına birer log satırı serpiştirmektir. Ancak doğru bir log seviye stratejisi kurulmadığında, geliştiricinin lokal bilgisayarında hayat kurtaran o satırlar, canlı sunucularda diskleri dolduran, CPU’yu eriten ve operasyon ekiplerini canından bezdiren birer canavara dönüşüyor.

Saha tecrübem boyunca loglama yüzünden çöken çok sistem gördüm. Bir keresinde, bir avuç mikroservisin debug logları yüzünden kısa sürede diskin tamamen dolduğuna ve bunun sonucunda veritabanının kilitlendiğine şahit oldum. Bu yazıda, loglamanın sadece teknik bir detay değil, aynı zamanda yazılım ekibi ile operasyon ekibi arasındaki o ince empati köprüsü olduğunu kendi deneyimlerim üzerinden anlatacağım.

Log Seviye Stratejisi: Rahatlığın Getirdiği Gizli Maliyet

Geliştiriciler olarak çoğunlukla kodun yazım aşamasına odaklanırız. “Buraya bir log atayım da ne olur ne olmaz, hata çıkarsa bakarız” düşüncesi, aslında gelecekteki kendimize veya sistem yöneticisine bırakılmış saatli bir bombadır. Eğer log seviye stratejisi projenin başında net kurallarla belirlenmediyse, her geliştirici kendi yoğurt yiyişine göre log seviyesi seçmeye başlar.

# Geliştirici A'nın tercihi (Fazla iyimser)
logger.info("Kullanıcı sisteme girdi, işlemler başlıyor...")

# Geliştirici B'nin tercihi (Paranoyak)
logger.debug(f"SQL sorgusu tetiklendi: SELECT * FROM users WHERE id = {user_id}")

Yukarıdaki basit örnek bile üretim ortamında büyük farklar yaratır. İkinci satırdaki gibi binlerce kullanıcının bağlandığı bir sistemde her SQL sorgusunu dinamik string formatlama ile loglamak, disk I/O limitlerini zorlamanın en kestirme yoludur. Bu hata genellikle sinsi ilerler: Nginx reverse proxy arkasındaki uygulama sunucusunun yanıt süresi belirgin biçimde fırlar, sebebi de tamamen disk yazma kuyruğunun şişmesidir.

DEBUG Seviyesinin Üretim Ortamındaki İhaneti

DEBUG seviyesi, adından da anlaşılacağı üzere sadece geliştirme (development) ve test aşamalarında kullanılmak üzere tasarlanmıştır. Üretim ortamında bu seviyeyi açık bırakmak, sisteme yapılabilecek en büyük kötülüklerden biridir. Bir üretim ERP’sinin stok modülünü yazarken, depodaki el terminallerinden gelen her barkod okuma işlemini DEBUG seviyesinde loglamıştık.

Sistem canlıya geçtikten kısa süre sonra, systemd-journald servisinin CPU tüketimi tavan yaptı. Journald, gelen aşırı log yükü karşısında kendi koruma mekanizmasını devreye soktu ve logları drop etmeye (dökmeye) başladı. Sonuç olarak, gerçek bir hata oluştuğunda elimizde o hataya dair hiçbir iz kalmamıştı çünkü sistem gürültüden boğulmuştu.

# journalctl çıktısında karşılaştığımız o meşhur uyarı satırı:
Jun 06 14:20:11 srv-erp-01 systemd-journald[452]: Suppressed 8420 messages from /user.slice/user-1000.slice

Eğer log seviyeniz canlıda DEBUG olarak kalırsa, sadece diski doldurmazsınız; aynı zamanda hassas verilerin (kişisel veriler, şifreler, token bilgileri) log dosyalarına sızma riskini de katlarsınız. Güvenlik tarafında kernel hardening ve switch hardening gibi konularla ne kadar uğraşırsanız uğraşın, uygulama seviyesindeki bu dikkatsizlik tüm güvenlik duvarlarınızı anlamsız kılabilir.

INFO Seviyesinin Sınırları: “Gürültü” ile “Sinyal” Arasındaki İnce Çizgi

Peki, INFO seviyesinde ne loglamalıyız? Bu soru, yazılım mimarisinin en kritik tartışma konularından biridir. INFO, sistemin normal işleyişi sırasındaki önemli durum değişikliklerini belirtmelidir. Her döngünün (loop) içindeki adımı değil, sadece o döngünün başarıyla tamamlandığını veya başladığını göstermelidir.

Bir üretim ERP’sinde tasarladığım yapay zeka destekli üretim planlama modülünde, log seviyelerini şu şekilde kategorize etmiştim:

Log Seviyesi Ne Zaman Kullanılır? Hedef Kitle Örnek Senaryo
DEBUG Detaylı kod akışı, değişken durumları Geliştirici Connection pool active connections: 14
INFO İş mantığı başlangıç ve bitişi Sistem Yöneticisi AI Production Plan #4812 started.
WARNING Beklenmeyen ama sistemin tolere ettiği durumlar L1 Destek / Ops Database connection retry #1 failed. Retrying...
ERROR İşlemin yarıda kalması, müdahale gereksinimi SRE / L2 Destek Failed to write plan to DB. Transaction aborted.

Bu tabloya sadık kalmak, operasyon ekibinin gece yarısı gereksiz yere uykusundan uyanmasını engeller. Eğer INFO seviyesini bir DEBUG gibi kullanırsanız, log izleme araçlarınızda (OpenSearch, Grafana Loki gibi) saniyede binlerce satır akar ve gerçek bir anomalinin tespiti imkansız hale gelir.

ERROR ve WARNING: Ne Zaman Alarma Basmalıyız?

En çok karıştırılan iki kavram: Bir durum ne zaman WARNING, ne zaman ERROR’dur? Benim bu konudaki kuralım çok basittir: Eğer bir log satırı için bir insanın hemen yatağından kalkıp müdahale etmesi gerekmiyorsa, o log ERROR değildir.

Geliştirdiğim bir mobil uygulamanın backend tarafında Sentry üzerinde çok yüksek sayıda unhandled exception (hata) biriktiğini gördüm. Detaylıca incelediğimde, bunların büyük çoğunluğunun aslında istemci tarafındaki ağ kopmalarından kaynaklanan, sunucunun hiçbir şey yapamayacağı geçici bağlantı hataları olduğunu fark ettim. Bunlar ERROR olarak işaretlendiği için nöbetçi mühendis sık sık uyarı alıyordu ve bir süre sonra bu uyarıları tamamen görmezden gelmeye (alert fatigue) başlamıştı.

# KÖTÜ PRATİK (Her hatayı felaket gibi göstermek)
try:
    response = requests.get("https://api.external-service.com/data", timeout=5)
except requests.exceptions.Timeout as e:
    logger.error(f"External API timeout! Error: {e}") # Bu bir ERROR değil, geçici bir durumdur.

# İYİ PRATİK (Tolere edilebilir durumları WARNING ile geçmek)
try:
    response = requests.get("https://api.external-service.com/data", timeout=5)
except requests.exceptions.Timeout as e:
    logger.warning("External API timeout. Retrying with fallback data.")
    response = get_cached_fallback_data()

Eğer dış servis kesintisi sistemin tamamen durmasına yol açmıyorsa ve uygulamanız bunu tolere edebiliyorsa (örneğin önbellekten veri sunarak), bu durum bir WARNING’dir. Ancak tüm sistemin durmasına yol açan, veritabanı bağlantısının tamamen kopması veya diskte yer kalmaması gibi durumlar gerçek birer ERROR’dur ve anında alarm tetiklemelidir.

Log Yönetiminde İki Büyük Günah: Boş Catch Blokları ve String Formatlama

Yazılım geliştirme sürecinde sıkça yapılan iki büyük teknik hata, tüm log seviye stratejinizi sıfırlayabilir. Birincisi, hataları yutup hiçbir yere yazmamaktır (swallowing exceptions). İkincisi ise logları yapılandırılmamış (unstructured) düz metin olarak yazıp, sistemin analiz edilmesini zorlaştırmaktır.

Boş bir catch bloğu, bir sorunun sessizce büyümesine zemin hazırlar; örneğin yoğun bir PostgreSQL replikasyon yapısında WAL bloat (arka arkaya biriken işlem günlükleri) gibi bir problemin kaynağını ararken, hatayı yutan bir fonksiyon yüzünden iz sürmek çok daha zor hale gelir.

# SESSİZ ÖLÜM (Boş catch bloğu)
try:
    process_payment(order_id)
except Exception:
    pass # Asla bunu yapmayın! Sistem hata aldığını bilmez.

# YAPILANDIRILMIŞ LOGLAMA (Structured Logging)
import json
import logging

logger = logging.getLogger("payment_processor")

def process_payment_safe(order_id):
    try:
        # Ödeme işlemleri...
        pass
    except Exception as e:
        # JSON formatında log üreterek analiz araçlarının işini kolaylaştırıyoruz
        log_payload = {
            "event": "payment_failed",
            "order_id": order_id,
            "error_message": str(e),
            "status": "failed"
        }
        logger.error(json.dumps(log_payload))

Yapılandırılmış loglama (JSON formatı), modern log analiz sistemlerinin logları kolayca indekslemesini sağlar. Bu sayede, “Hangi siparişlerde ödeme hatası alınmış?” sorusunun cevabını saniyeler içinde bulabiliriz. Düz metin loglarda ise regex yazarak debelenmek zorunda kalırız ki bu da operasyonel süreyi uzatır.

İnsan Odaklı Bir Operasyon Kültürü Kurmak

Yazının başında da belirttiğim gibi, loglama aslında tamamen bir kültür ve empati meselesidir. Kodu yazan geliştirici ile o kodu canlıda ayakta tutmaya çalışan sistem yöneticisi veya site güvenliği mühendisi (SRE) arasındaki ilişkiyi belirler. Geliştirici, yazdığı her log satırının bir maliyeti olduğunu bilmeli; operasyoncu ise log seviyelerini dinamik olarak değiştirebileceği altyapıyı (örneğin log level hot-reload) sağlamalıdır.

Bu noktada dinamik log seviyesi büyük bir esneklik sağlar. Örneğin canlı bir geçiş (migration) sırasında log seviyesini geçici olarak DEBUG’a çekip, geçiş tamamlandıktan sonra sunucuyu yeniden başlatmadan tekrar INFO seviyesine indirmek hayat kurtarır. Nginx reverse proxy ayarlarında veya systemd servis unit’lerinde yapacağınız ufak bir sinyal (SIGHUP) yapılandırması, uygulamanızı kapatıp açmadan log seviyesini değiştirmenize olanak tanır.

Sonuç olarak; loglama, geliştiricinin lokalinde rahat etmesi için rastgele kullanacağı bir debug aracı değildir. Loglar, üretim ortamındaki sisteminizin kara kutusudur. O kutuyu gürültüyle doldurup işe yaramaz hale getirmek de, net ve okunabilir sinyallerle donatıp hayat kurtarmasını sağlamak da bizim elimizde.

Net pozisyonum: Üretim ortamında DEBUG log seviyesini tamamen yasaklayın, loglarınızı mutlaka JSON formatında yapılandırılmış hale getirin ve her hata logunun arkasına “Bu hata gece yarısı birini uyandırmalı mı?” sorusunu ekleyin. Bir sonraki yazımda, PostgreSQL üzerindeki indeksleme stratejilerinde yaptığımız hataları ve sorgu planlayıcısının (planner) nasıl ters köşe olabildiğini anlatacağım.

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

Sıkça Sorulanlar

Bu makale ile ilgili okurların sorduğu yaygın sorular.

Log seviye stratejisi oluştururken nelere dikkat etmem gerekir?
Benim deneyimime göre, log seviye stratejisi oluştururken öncelikle üretim ortamındaki performans etkilerini dikkate almalısınız. Fazla loglama, sistemlerin yavaşlamasına ve operasyonel yükün artmasına neden olabilir. Bu nedenle, loglama düzeyini dikkatli bir şekilde ayarlamak ve gereksiz logları engellemek önemlidir.
Hangi araçları kullanarak log seviye stratejimi optimize edebilir ve üretim ortamındaki operasyonel yükü azaltabilirim?
Ben genellikle loglama kütüphanelerini ve araçlarını kullanırım. Örneğin, Python'da logging kütüphanesini kullanarak log seviyelerini ayarlayabilir ve gereksiz logları engelleyebilirsiniz. Ayrıca, loglama araçları gibi ELK Stack (Elasticsearch, Logstash, Kibana) veya Splunk gibi araçları kullanarak logları merkezi bir şekilde yönetebilir ve analiz edebilirsiniz.
Log seviye stratejisinin avantajları ve dezavantajları nelerdir?
Log seviye stratejisinin avantajları arasında, üretim ortamındaki hataları ve sorunları daha kolay tespit edebilme ve sistemlerin performansını artırma olanakları bulunur. Ancak, dezavantajları arasında fazla loglama nedeniyle disk alanı ve CPU kullanımının artması ve operasyon ekiplerinin iş yükünün artması yer alır. Benim deneyimime göre, doğru bir log seviye stratejisi oluşturmak, bu avantajları ve dezavantajları dengeli bir şekilde yönetmeyi gerektirir.
Log seviye stratejisi oluştururken en yaygın hatalardan kaçınmak için hangi ipuçlarını takip edebilirim?
Benim deneyimime göre, en yaygın hatalardan biri, log seviyelerini doğru şekilde ayarlamamaktır. Bu nedenle, log seviyelerini dikkatli bir şekilde ayarlayın ve gereksiz logları engelleyin. Ayrıca, loglama düzeyini üretim ortamındaki performans etkileri doğrultusunda düzenli olarak güncelleyin ve ayarlayın. Bu ipuçlarını takip ederek, log seviye stratejisinin avantajlarını maksimum düzeyde elde edebilirsiniz.
ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

✉️ Ücretsiz · Spam yok · İstediğin an çık

Yeni yazılardan haberdar olun

Yeni içerikler ve teknik notlar e-postanıza gelsin.

  • 📌
    Haftanın en iyisi Sadece okumaya değer tek yazı
  • 🔧
    Alet çantası Bu hafta kullandığım araçlar
  • 🧠
    Perde arkası Blog'a girmeyen notlar

Spam yapmıyoruz. İstediğiniz zaman ayrılabilirsiniz. · Sadece Umami (self-hosted, Google yok) ile takip.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar