Yapılandırılmış Loglama — Gece 2'de Doğru Satırı Bulmak
Önce şunu oku: Actuator ve Gözlemlenebilirlik — Sağlık, Metrik, İz
30 saniyede özet
Bir hata çıktığında cevap loglardadır, ama onu bulup bulamayacağını logları nasıl yazdığın belirler. Alanlara ayrılmış JSON satırlar, her isteğin taşıdığı bir trace id ve maskelenmiş kişisel veri, aramayı tahminden kesinliğe taşır.
Gece 2’de telefonun çalıyor: bir müşterinin havalesi başarısız olmuş. Cevap bir yerlerde, üç servisin binlerce satırlık logunda yazılı. Onu beş dakikada mı, iki saatte mi bulacağın, logların nasıl yazıldığına bağlı.
-
Bayt: Müşteri 42'nin havalesi başarısız olmuş. Loglarda '42' diye aradım.
-
Sen: Ne çıktı?
-
Bayt: Dokuz satır! Tutar 42 lira, sipariş 4211, port 8042... hangisi bizim müşteri?
-
Bayt: Aramayı değil, yazmayı düzeltmek gerek. Logu bir veri gibi yazalım.
Logu veri gibi yazmak
Serbest metin log bir cümledir: “transfer failed for customer 42”. structured loggingLog satırlarını alanlardan oluşan kayıtlar (çoğunlukla JSON) olarak yazmak. Arama metin içinde değil, customerId gibi alanlarda yapılır.Sözlükte gör → ise alanlardan oluşur: level, customerId, transferId, msg. Arama metin içinde değil, alanlarda yapılır.
Spring Boot 3.4’ten beri bunun için bir ayar yeter: logging.structured.format.console: ecs. İsteğe özel alanlar ise MDCMapped Diagnostic Context: SLF4J/Logback'in thread'e bağlı anahtar-değer tablosu. Log pattern'i buradan okur; Micrometer Tracing traceId ve spanId'yi oraya koyar.Sözlükte gör → ile eklenir ve o isteğin bütün satırlarına kendiliğinden yazılır.
Kafam karıştı, daha basit anlat
Log bir cümle değil, etiketli bir kayıt olsun. Arama metinde değil, etikette yapılsın.
Yapılandırılmış log nedir?
Serbest metin loglarda '42' diye arama yaptın. Neden alakasız satırlar da geldi?
Bir isteği izlemek
Havale isteği gateway, transfers ve ledger servislerinden geçti. Loglarda trace id yok. Saat 14:02:11'de dört farklı istek var. Ledger'daki hata satırı bu havaleye mi ait? Cevabı göster
Bilemezsin. Servisler arasında ortak bir kimlik olmadan satırları ancak zamana bakarak tahminle eşleştirirsin. Aynı saniyede dört istek varsa tahmin dörtte bir şanstır.
Adım adım oku
- Karalanmış notlu kutular: '42' her yerde geçiyor.
- Etiketli kutular: yalnızca 'müşteri: 42' olanlar seçiliyor.
- Renkli ip: bir isteğin üç servisteki kutuları birbirine bağlı.
- Etiket ve ip birlikte: kök neden tek zincirde.
Trace id bir isteğin kimliğidir: istek gateway’e girdiği an üretilir ve her servise traceparent başlığıyla taşınır. Spring Boot’ta Micrometer Tracing onu her log satırına kendiliğinden ekler.
Kafam karıştı, daha basit anlat
Trace id, bir isteğin bütün servislerdeki satırlarını bağlayan iptir. Onunla bir isteği baştan sona izlersin.
Trace id ne işe yarar?
Trace id olmadan üç servisin logunda bir isteği izlemeye çalışıyorsun. Ne yapmak zorunda kalırsın?
Kendin gör
Müşteri 42'nin havalesi neden başarısız?
Tohum 94664Bir log satırı böyle yazılıyor:
14:02:11 ERROR transfer failed for customer 42 iban TR330006100519786457841326
Oynat ya da adımla: her adım aramanın bir aşaması.
Şu an ne oldu?
Saat 14:02, bir havale başarısız
Cevap üç servisin loglarında. Onu ne kadar hızlı bulacağını, logları nasıl yazdığın belirliyor.
Görevler0/3
Aramada alakasız satırlara boğulaçık
İpucu
Varsayılan ayarlar yeter.
Kök nedeni kesin olarak bulaçık
İpucu
İki alışkanlık birlikte gerekiyor.
Kök nedeni bul ve log'da hiçbir açık IBAN bırakmaaçık
İpucu
Üç anahtar.
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanla oynat. Dokuz eşleşme, kök neden belirsiz, IBAN açık.
- Yapılandırılmış log’u aç. Üç satır, üçü de bu müşterinin; ama servisler arası bağ yok.
- Trace id’yi aç. Kök neden bulundu: ledger timeout.
- Kişisel veriyi maskele. Aynı sonuç, ama log’da IBAN maskeli.
MDC'ye bir alan koymak ne sağlar?
MDC'ye müşteri numarası konuyor ama istek bitince temizlenmiyor. Thread havuzunda ne olur?
Tuzaklar
Log’da kişisel veri. IBAN, kart numarası ya da kimlik numarası log’a açık yazılırsa, loglara erişen herkes onları görür. Maskelemeyi tek bir yerde, değer nesnesinin kendisinde yap.
Her şey DEBUG. Canlıda bütün paketleri DEBUG seviyesinde loglamak, sinyali gürültüye gömer ve depolama maliyetini katlar. Varsayılan INFO, hata ayıklarken yalnızca ilgili paket DEBUG.
Hatayı yutmak. log.error("hata") deyip istisnanın kendisini yazmamak, yığın izini kaybettirir. İstisnayı son parametre olarak ver.
Kafam karıştı, daha basit anlat
Kişisel veriyi maskele, seviyeyi bilinçli seç, istisnayı satıra ekle.
Log'a IBAN'ın tamamını yazmanın riski nedir?
Aşağıdaki örnek bir bankanın havale servisinden: JSON log, istek boyunca taşınan müşteri numarası, kendini maskeleyen IBAN.
Derinleş · Havale servisi: aranabilir, izlenebilir, güvenli log 4 dosya · ~66 satır · ilk okumada atlayabilirsin
Kendini sına
Serbest metin log'da müşteri numarasıyla arama, yalnızca o müşterinin satırlarını getirir.
log.error("transfer failed") yazıldı ama istisna parametre olarak verilmedi. Sonuç?
Aklında kalacak üç şey
- 1 Serbest metin log'da arama, aradığın sayının geçtiği her satırı getirir. Alanlara ayrılmış JSON log'da müşteri numarasına göre süzersin ve yalnızca o müşterinin satırları gelir.
- 2 Bir isteğin bütün satırları servisler boyunca aynı trace id'yi taşırsa, isteği uçtan uca izlersin. Trace id yoksa satırları zamana bakarak tahminle eşleştirirsin.
- 3 IBAN ve kart numarası gibi kişisel veriler log'a maskelenerek yazılır. Loglar geniş bir ekibe açıktır ve uzun süre saklanır.
4 kart sonraki derste seni bekliyor