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

Structured vs Unstructured Logging: Gözlemlenebilirlik Temelleri

Sistem ve uygulama loglarını yapısal (structured) veya yapısal olmayan (unstructured) formatlarda tutmanın farklarını, faydalarını ve gerçek dünya…

100%

Herhangi bir sistemin veya uygulamanın sorunsuz çalıştığını anlamak için loglara bakmak kritik. Bu konuda iki ana yaklaşım var: Unstructured (yapısal olmayan) ve Structured (yapısal) logging. Benim için loglar, bir uygulamanın beyni gibi; ne düşündüğünü, ne yaşadığını ve nerede takıldığını bana anlatan bir günlük. Geçtiğimiz 20 yılda, binlerce sunucunun, yüzlerce uygulamanın logunu inceledim ve bu süreçte iki yaklaşımın da kendine göre avantajları ve dezavantajları olduğunu gördüm.

Özellikle bir üretim firmasının ERP’sini geliştirirken, anlık stok hareketlerinden faturalandırma süreçlerine kadar her adımın loglanması gerekiyordu. Başlangıçta geleneksel unstructured loglar kullandık, ancak sistem büyüdükçe bu logların yönetimi kabusa dönüştü. Nerede ne oldu, hangi siparişte hata var, hangi kullanıcı hangi işlemi ne zaman yaptı gibi soruların cevabını bulmak saatler sürüyordu. Bu yüzden, gözlemlenebilirliği artırmak ve sorunları daha hızlı çözmek adına structured logging’e geçiş kaçınılmaz oldu.

Unstructured Logging: Kolay Başlangıç, Zor Bakım

Unstructured logging, en basit tabirle, serbest metin formatında yazılan loglardır. Yani, uygulamanızın “şu oldu”, “bu hata”, “işlem tamamlandı” gibi mesajları doğrudan bir dosyaya yazdırmasıdır. Apache veya Nginx’in varsayılan access.log kayıtları buna iyi bir örnektir. Okuması ilk bakışta kolay gibi görünse de, özellikle problem anlarında veya belirli kalıpları ararken işler zorlaşır.

Benim deneyimimde, küçük projelerde veya hızlı prototiplemelerde unstructured loglar yeterli olabilir. Örneğin, kendi yan ürünlerimden birinin ilk versiyonlarında, sadece print() komutlarıyla loglama yapıyordum. Ancak sistem büyüyüp karmaşıklaştığında, “geçen hafta saat 03:00’te hangi kullanıcının hangi API’yi çağırdığını” bulmak için grep komutlarıyla saatlerce uğraşmak zorunda kaldım. Bu durum, özellikle yüzlerce GB log dosyası olan bir üretim ortamında tam bir eziyete dönüşebiliyor.

Bir keresinde, büyük bir TR e-ticaret sitesinde ödeme ağ geçidi entegrasyonunda bir sorun yaşadık. Loglarda “Payment failed” mesajı vardı, ancak neden başarısız olduğunu anlamak için ilgili transaction ID’sini, kullanıcı ID’sini ve hata kodunu aynı satırda bulmak gerekiyordu. Bu bilgileri içeren yüzlerce satırı tek tek grep -i "payment failed" | grep "TXN_12345" gibi komutlarla aramak, MTTR süremizi uzatıyordu. İşte bu noktada unstructured logların yetersiz kaldığını acı bir şekilde tecrübe ettim.

Structured Logging: Veri Tabanı Gibi Loglamak

Structured logging ise logları belirli bir formatta, genellikle anahtar-değer (key-value) çiftleri veya JSON gibi standart veri yapıları kullanarak kaydetmektir. Bu format, logların hem insanlar tarafından okunmasını kolaylaştırır hem de makine tarafından çok daha etkin bir şekilde işlenmesini sağlar. Her log kaydı, bir veri tabanındaki bir satır gibi, belirli alanlara (field) sahiptir.

Ben genellikle JSON formatını tercih ediyorum çünkü hem okunabilirliği yüksek hem de çoğu log toplama aracı (Loki, Elasticsearch, Splunk) tarafından doğal olarak destekleniyor. Bir ERP uygulamasında, her bir operasyonu (örneğin, “sipariş oluşturma”, “ürün sevkiyatı”) ayrı ayrı loglarken, bu operasyonla ilgili tüm detayları (kullanıcı ID’si, sipariş ID’si, işlem süresi, etkilenen ürünler) structured log olarak kaydettim. Bu sayede, “son 24 saat içinde hangi siparişler 10 saniyeden uzun sürdü?” gibi sorulara saniyeler içinde cevap bulabildik.

{
  "timestamp": "2026-05-22T10:30:00Z",
  "level": "INFO",
  "service": "order-management",
  "event": "order_created",
  "user_id": "USR-12345",
  "order_id": "ORD-67890",
  "item_count": 3,
  "total_amount": 150.75,
  "latency_ms": 120
}

Yukarıdaki gibi bir JSON log kaydı, sadece bir mesajdan çok daha fazlasıdır; sorgulanabilir bir veri noktasıdır. Bu bana, “PostgreSQL’de N+1 sorununu tespit ettiğimde” veya “Redis OOM eviction policy seçimlerinde hatalar” gibi durumlarda çok yardımcı oldu. Özellikle finansal işlem loglarının structured olması, regülasyon uyumluluğu ve denetim süreçleri için hayati önem taşır; hangi kullanıcının hangi saatte hangi işlemi yaptığını saniyeler içinde raporlayabilmek bu tür ortamlarda doğrudan bir gereksinimdir.

Neden Structured Logging Tercih Edilmeli? Pragmatik Yaklaşımım

Structured logging’i tercih etmemin temel nedeni, operasyonel verimlilik. Problemlerle karşılaştığımda, “nerede ve ne oldu?” sorusuna hızlıca cevap verebilmek, sistemin uptime’ını doğrudan etkiler. Benim için MTTR, yani ortalama çözüm süresi, her zaman en önemli metriklerden biri olmuştur. Structured loglar bu süreyi önemli ölçüde kısaltıyor.

Üretim bandındaki bir sensörden gelen anomaliyi tespit etmek gerektiğinde, loglar unstructured olsaydı yüzlerce sensörden gelen milyonlarca log satırında grep yapmak imkansıza yakındı. Ancak structured loglar sayesinde, sensor_id: "X" AND value > threshold gibi basit bir sorguyla anormalliği anında tespit edip otomatik bir uyarı tetikleyebildik. Bu sayede üretim hattının durma süresini belirgin biçimde azalttık.

Ayrıca, structured loglar sayesinde “gerçek-zamanlı dashboard tasarımı” yapmak çok daha kolay hale geliyor. Log toplama araçları, structured logları otomatik olarak parse edip grafiklere dökebilir. Bu sayede, anlık hataları, performans düşüşlerini veya belirli bir API’ye gelen istek sayısını canlı olarak izleyebiliyorum. Daha önce observability metrikleri ile sistem sağlığını izleme konusunda bahsettiğim gibi, görselleştirme, operasyonel zeka için olmazsa olmazdır.

Structured Logging Uygulama Stratejileri

Structured logging’i sistemlerime entegre etmek için farklı stratejiler izledim. Bu stratejiler genellikle uygulamanın büyüklüğüne, karmaşıklığına ve mevcut altyapıya göre değişir. Hangi yöntemi seçeceğiniz, projenizin ihtiyaçlarına ve ekibinizin yeteneklerine bağlıdır.

  1. Uygulama Seviyesinde Loglama: En doğrudan yöntemdir. Uygulama kodunuz içinde, log mesajlarını doğrudan JSON gibi structured bir formatta oluşturursunuz. Python’da logging modülü veya Java’da Logback/Log4j gibi kütüphaneler bu konuda gelişmiş destek sunar. Ben FastAPI ve Vue.js tabanlı bir ERP backend’inde genellikle python-json-logger gibi kütüphaneler kullandım.

    import logging
    import json_log_formatter
    
    formatter = json_log_formatter.JsonFormatter()
    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    logger = logging.getLogger(__name__)
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)
    
    # Örnek log kaydı
    logger.info("Order processed successfully", extra={
        "order_id": "ORD-123",
        "customer_id": "CUST-456",
        "amount": 99.99,
        "payment_method": "CreditCard"
    })
  2. Sidecar veya Log Agent Kullanımı: Bu yöntemde, uygulamanız hala unstructured loglar üretebilir, ancak ayrı bir “agent” (örneğin Fluentd, Filebeat veya Logstash) bu logları okuyup structured formata dönüştürür ve merkezi bir log sistemine gönderir. Özellikle legacy uygulamalarla çalışırken veya uygulamanın kendisini değiştirmek istemediğinizde bu yaklaşım kurtarıcıdır. Kendi VPS’imde, Nginx access loglarını Filebeat ile parse edip Loki’ye gönderiyorum. Bu, container orkestrasyonunda log yönetimi konusunda da önemli bir yaklaşımdır.

  3. Merkezi Log Yönetim Sistemleri: Toplanan structured logları depolamak, indekslemek, sorgulamak ve görselleştirmek için Loki, Elasticsearch (ELK Stack), Splunk gibi çözümler kullanılır. Bu sistemler, büyük ölçekli ve dağıtık mimarilerde gözlemlenebilirliğin temelini oluşturur. Ben genellikle Loki’yi tercih ediyorum çünkü hem resource dostu hem de Promtail ile entegrasyonu çok kolay.

Her stratejinin kendine göre bir maliyeti ve karmaşıklığı var. Uygulama seviyesinde loglama en esnek olanıdır ama kodda değişiklik gerektirir. Sidecar yaklaşımı daha az kod değişikliğiyle eski sistemleri entegre ederken, bir agent çalıştırma maliyeti getirir. Merkezi sistemler ise kurulum ve bakım açısından yatırım gerektirir.

Gerçek Dünya Senaryolarında Karşılaştığım Zorluklar

Structured logging’e geçmek her zaman güllük gülistanlık olmadı. Bu süreçte bazı beklenmedik zorluklarla karşılaştım. Bunlardan en önemlisi, log schema’sının evrimiydi. Bir uygulamayı geliştirirken, log’a eklemek istediğim alanlar zamanla değişebiliyor. Örneğin, başlangıçta order_id yeterliyken, daha sonra tracking_number veya carrier_id gibi alanlara da ihtiyaç duyulabiliyor.

Bu durum, log toplama sistemlerindeki indekslerin veya parse kurallarının sürekli güncellenmesini gerektirdi. Özellikle Elasticsearch gibi schema-on-read yerine schema-on-write çalışan sistemlerde, schema değişiklikleri indeks yenileme veya veri kaybı gibi sorunlara yol açabiliyordu. Bu yüzden, log schema’sını baştan iyi tasarlamak ve esneklik payı bırakmak gerektiğini öğrendim. Benim tavsiyem, her zaman minimum gerekli alanı loglamak ve daha sonra ihtiyaç duyulursa eklemeler yapmaktır, ancak bunu yaparken geriye dönük uyumluluğu gözetmek şart.

Bir diğer zorluk da log hacmiydi. Structured loglar, unstructured loglara göre genellikle daha fazla yer kaplar. Yüksek hacimli bir üretim ortamında günlük log üretimi ciddi boyutlara ulaştığında, depolama ve işleme maliyetleri ciddi bir problem haline geldi. Bu durumda, log seviyelerini optimize etmek (DEBUG loglarını sadece geliştirme ortamında tutmak), gereksiz alanları loglamamak ve log retention politikalarını sıkı tutmak gibi önlemler almak zorunda kaldım.

Journald ve Systemd’nin Rolü: Hibrit Yaklaşım

Linux sistemlerinde systemd ve journald ikilisi, structured logging konusunda bize doğal bir avantaj sunar. journald, tüm sistem loglarını ikili (binary) bir formatta, ancak structured bir şekilde depolar. Yani, her log kaydı otomatik olarak _SYSTEMD_UNIT, _PID, MESSAGE, _HOSTNAME gibi alanlarla etiketlenir. Bu, uygulama loglarınızı journald’ye göndererek ek bir agent’a ihtiyaç duymadan structured loglamanın faydalarından yararlanabileceğiniz anlamına gelir.

Ben, çoğu zaman uygulamalarımın loglarını standart çıktıya (stdout/stderr) yazdırıp, systemd servis tanımında StandardOutput=journal veya StandardOutput=syslog kullanarak journald’ye yönlendiriyorum. Bu sayede, journalctl komutuyla uygulamamın loglarına kolayca filtre uygulayabiliyorum.

# Sadece bir servise ait logları filtrele
journalctl -u my-web-app.service

# Belirli bir PID'ye ait logları ve sadece hataları göster
journalctl _PID=12345 -p err

# JSON formatında çıktı al
journalctl -u my-web-app.service -o json

journalctl -o json çıktısı, uygulamanızın stdout’a yazdığı metin loglarını da içeren, zengin structured veriler sunar. Bu hibrit yaklaşım, hem basit hem de güçlüdür. Özellikle container ortamlarında docker logs çıktılarının journald’ye yönlendirilmesi, log yönetimini büyük ölçüde kolaylaştırıyor. Benim için bu, bare-metal sunucular ile container’ları bir arada kullandığım hibrit dağıtım mimarilerinde vazgeçilmez bir yaklaşım oldu.

Sonuç

Structured logging, modern sistemlerin gözlemlenebilirlik gereksinimlerini karşılamak için vazgeçilmez bir araç. Başlangıçta biraz daha fazla çaba gerektirse de, uzun vadede sorun giderme süresini kısaltır, operasyonel maliyetleri düşürür ve sistemlerinizin sağlığı hakkında daha derinlemesine bilgi edinmenizi sağlar. Unstructured loglarla boğuştuğum zamanları düşününce, structured logging’e geçiş kararımın ne kadar doğru olduğunu bir kez daha anlıyorum.

Eğer hala sistemlerinizde unstructured loglar kullanıyorsanız, structured logging’e geçişi ciddi şekilde düşünmenizi tavsiye ederim. Küçük adımlarla başlayabilir, kritik uygulamalarınızdan birinde denemeler yapabilirsiniz. Unutmayın, iyi loglanmış bir sistem, karanlıkta yolunu bulmaya çalışan bir mühendis için fener gibidir. Bir sonraki yazıda, log metriklerini kullanarak anomali tespiti üzerine konuşacağız.

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.

Structured logging'e geçişte ilk adım olarak hangi aracı kullandınız ve nedenini anlatabilir misiniz?
Ben ilk olarak Python projelerimde `structlog` kütüphanesini kullanarak structured logging'e geçtim. Çünkü mevcut `logging` modülüyle uyumlu, esnek yapıda ve JSON çıktıları doğrudan elde edilebiliyordu. ERP sistemimde logların SIEM sistemine entegre olması gerekiyordu, bu da `structlog` ile çok kolaylaştı. Başlangıçta küçük bir modülde denedim, hata durumlarını daha net görebildim. Sonrasında tüm servislere yaydım. En büyük avantajı, loglara ek bilgileri (kullanıcı ID, işlem tipi gibi) standart bir biçimde ekleyebilmem oldu.
Unstructured loglar gerçekten tamamen kötü mü, yoksa hâlâ kullanılabilecek durumlar mı var?
Kesinlikle unstructured loglar 'tamamen kötü' değil. Benim deneyimimde, özellikle geliştirme ortamında veya küçük araçlarda hâlâ değerleri var. Örneğin, bir CLI aracı yazarken ilk hata ayıklama adımlarında `print()` ile hızlıca durum kontrolü yapmak çok pratik. Ancak üretim ortamında, özellikle dağıtık sistemlerde bu yaklaşım sürdürülemez. Kuralım şu: prototip ve lokal geliştirme için unstructured, üretim ve gözlemlenebilirlik gerektiren sistemler için structured kullan. Bu ayrımı yapmak, hem verimlilik hem de bakım kolaylığı sağlıyor.
Structured logging'e geçerken karşılaştığınız en büyük hata nedir ve nasıl çözdünüz?
En büyük hatam, loglara çok fazla, gereksiz alan eklemeye başlamam oldu. Başlangıçta 'belki lazım olur' mantığıyla her değişkeni logluyordum. Bu, log hacmini patlattı ve analiz zorlaştı. Çözüm olarak, loglamak istediğim her alanı 'Bu alan bir sorunu çözmek için kullanılır mı?' sorusuyla sorgulamaya başladım. Ayrıca, log seviyelerini (debug, info, error) daha disiplinli kullanmaya özen gösterdim. Zamanla, hangi bilginin gerçekten değerli olduğunu anlamak için birkaç kez dönüp logları analiz ettim. Deneme-yanılma süreci oldu, ama disiplin kritik.
Birçok kişi 'structured logging sadece büyük sistemlerde işe yarar' diyor. Bu görüşe katılıyor musunuz?
Bu görüşe katılmıyorum. Ben, orta ölçekli bir ERP sisteminde bile structured logging'in büyük fark yarattığını gördüm. Küçük takımlar bile, loglara dayalı hata analizi yapıyorsa, yapısal loglamadan faydalanır. Örneğin, bir siparişte hata olduğunda, sadece 'Sipariş oluşturulamadı' demek yerine, 'order_id=1234, user_id=567, error=payment_failed' gibi bilgileri loglamak, sorunu çok daha hızlı bulmamı sağladı. Yani sistem boyutundan çok, 'ne kadar hızlı sorun çözmek istiyorsun?' meselesi. Structured logging, büyüdükçe değil, acı çekmeye başladıkça gereklidir.
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